Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f7bbd0c93e |
@@ -497,6 +497,11 @@ impl NymApiClient {
|
||||
Ok(nodes)
|
||||
}
|
||||
|
||||
/// retrieve basic information for all bonded nodes on the network
|
||||
pub async fn retrieve_basic_nodes_batch(&self, node_ids: Vec<u32>) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
|
||||
Ok(self.nym_api.retrieve_basic_nodes_batch(&node_ids).await?.nodes)
|
||||
}
|
||||
|
||||
pub async fn health(&self) -> Result<ApiHealthResponse, ValidatorClientError> {
|
||||
Ok(self.nym_api.health().await?)
|
||||
}
|
||||
|
||||
@@ -253,10 +253,10 @@ pub trait NymApiClientExt: ApiClient {
|
||||
self.get_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
"unstable",
|
||||
routes::UNSTABLE,
|
||||
routes::NYM_NODES_ROUTES,
|
||||
"mixnodes",
|
||||
"skimmed",
|
||||
routes::SKIMMED,
|
||||
],
|
||||
NO_PARAMS,
|
||||
)
|
||||
@@ -269,10 +269,10 @@ pub trait NymApiClientExt: ApiClient {
|
||||
self.get_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
"unstable",
|
||||
routes::UNSTABLE,
|
||||
routes::NYM_NODES_ROUTES,
|
||||
"gateways",
|
||||
"skimmed",
|
||||
routes::SKIMMED,
|
||||
],
|
||||
NO_PARAMS,
|
||||
)
|
||||
@@ -318,9 +318,9 @@ pub trait NymApiClientExt: ApiClient {
|
||||
self.get_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
"unstable",
|
||||
routes::UNSTABLE,
|
||||
routes::NYM_NODES_ROUTES,
|
||||
"skimmed",
|
||||
routes::SKIMMED,
|
||||
"entry-gateways",
|
||||
"all",
|
||||
],
|
||||
@@ -355,9 +355,9 @@ pub trait NymApiClientExt: ApiClient {
|
||||
self.get_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
"unstable",
|
||||
routes::UNSTABLE,
|
||||
routes::NYM_NODES_ROUTES,
|
||||
"skimmed",
|
||||
routes::SKIMMED,
|
||||
"mixnodes",
|
||||
"active",
|
||||
],
|
||||
@@ -392,9 +392,9 @@ pub trait NymApiClientExt: ApiClient {
|
||||
self.get_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
"unstable",
|
||||
routes::UNSTABLE,
|
||||
routes::NYM_NODES_ROUTES,
|
||||
"skimmed",
|
||||
routes::SKIMMED,
|
||||
"mixnodes",
|
||||
"all",
|
||||
],
|
||||
@@ -403,6 +403,31 @@ pub trait NymApiClientExt: ApiClient {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Send a Post request with a set of node ids. A successful response will contain descriptors
|
||||
/// for all nodes associated with those node IDs available in the current full topology.
|
||||
///
|
||||
/// If a provided node ID is not present there will be no descriptor for that node in the response.
|
||||
///
|
||||
/// If no node IDs are provided the response will contain no descriptors.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn retrieve_basic_nodes_batch(
|
||||
&self,
|
||||
node_ids: &[NodeId],
|
||||
) -> Result<CachedNodesResponse<SkimmedNode>, NymAPIError> {
|
||||
self.post_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
routes::UNSTABLE,
|
||||
routes::NYM_NODES_ROUTES,
|
||||
routes::SKIMMED,
|
||||
routes::BATCH,
|
||||
],
|
||||
NO_PARAMS,
|
||||
node_ids,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
async fn get_basic_nodes(
|
||||
&self,
|
||||
@@ -427,9 +452,9 @@ pub trait NymApiClientExt: ApiClient {
|
||||
self.get_json(
|
||||
&[
|
||||
routes::API_VERSION,
|
||||
"unstable",
|
||||
routes::UNSTABLE,
|
||||
routes::NYM_NODES_ROUTES,
|
||||
"skimmed",
|
||||
routes::SKIMMED,
|
||||
],
|
||||
¶ms,
|
||||
)
|
||||
|
||||
@@ -70,3 +70,7 @@ pub const SERVICE_PROVIDERS: &str = "services";
|
||||
|
||||
pub const DETAILS: &str = "details";
|
||||
pub const NETWORK: &str = "network";
|
||||
|
||||
pub const UNSTABLE: &str = "unstable";
|
||||
pub const SKIMMED: &str = "skimmed";
|
||||
pub const BATCH: &str = "batch";
|
||||
|
||||
@@ -26,6 +26,7 @@ use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
pub(crate) mod legacy;
|
||||
pub(crate) mod unstable;
|
||||
pub(crate) mod topology;
|
||||
|
||||
pub(crate) fn nym_node_routes() -> Router<AppState> {
|
||||
Router::new()
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#![warn(missing_docs)]
|
||||
#![warn(rustdoc::missing_crate_level_docs)]
|
||||
|
||||
use crate::{
|
||||
node_status_api::models::{AxumErrorResponse, AxumResult},
|
||||
support::http::{helpers::NodeIdParam, topology_cache::{TopologyCache, PayloadFormat}},
|
||||
};
|
||||
|
||||
use axum::{
|
||||
extract::{Path, Query, State},
|
||||
routing::{get, post},
|
||||
Json, Router,
|
||||
};
|
||||
use nym_mixnet_contract_common::{Interval, NodeId};
|
||||
use nym_api_requests::models::RewardedSetResponse;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
type SkimmedNodes = AxumResult<Json<TopologyResponse>>;
|
||||
|
||||
#[derive(Debug, Deserialize, utoipa::IntoParams)]
|
||||
#[into_params(parameter_in = Query)]
|
||||
struct TopologyParams {
|
||||
#[allow(dead_code)]
|
||||
semver_compatibility: Option<String>,
|
||||
|
||||
// Identifier for the current epoch of the topology state. When sent by a client we can check if
|
||||
// the client already knows about the latest topology state, allowing a `no-updates` response
|
||||
// instead of wasting bandwidth serving an unchanged topology.
|
||||
epoch_id: Option<u32>,
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub(crate) fn topology_routes() -> Router<Arc<TopologyCache>> {
|
||||
Router::new()
|
||||
.route("layer-assignments", get(layer_assignments))
|
||||
.nest(
|
||||
"/skimmed",
|
||||
Router::new()
|
||||
.route("/", get(nodes_basic_all))
|
||||
.route("batch", post(nodes_basic_batch))
|
||||
.route("/:node_id", get(node_basic)),
|
||||
)
|
||||
// // NOT IMPLEMENTED
|
||||
// .nest(
|
||||
// "/semi-skimmed",
|
||||
// Router::new().route("/", get(nodes_expanded_all)),
|
||||
// )
|
||||
// .nest(
|
||||
// "/full-fat",
|
||||
// Router::new().route("/", get(nodes_detailed_all)),
|
||||
// )
|
||||
}
|
||||
|
||||
async fn nodes_basic_all(
|
||||
State(state): State<Arc<TopologyCache>>,
|
||||
Query(query_params): Query<TopologyParams>,
|
||||
) -> AxumResult<Json<TopologyResponse>> {
|
||||
Err(AxumErrorResponse::not_implemented())
|
||||
}
|
||||
|
||||
async fn nodes_basic_batch(
|
||||
State(state): State<Arc<TopologyCache>>,
|
||||
Query(query_params): Query<TopologyParams>,
|
||||
Json(node_ids): Json<Vec<NodeId>>,
|
||||
) -> AxumResult<Json<TopologyResponse>> {
|
||||
Err(AxumErrorResponse::not_implemented())
|
||||
}
|
||||
|
||||
async fn node_basic(
|
||||
Path(NodeIdParam { node_id }): Path<NodeIdParam>,
|
||||
State(state): State<Arc<TopologyCache>>,
|
||||
Query(query_params): Query<TopologyParams>,
|
||||
) -> AxumResult<Json<TopologyResponse>> {
|
||||
Err(AxumErrorResponse::not_implemented())
|
||||
}
|
||||
|
||||
async fn layer_assignments(
|
||||
State(state): State<Arc<TopologyCache>>,
|
||||
Query(query_params): Query<TopologyParams>,
|
||||
) -> AxumResult<Json<LayerAssignmentsResponse>> {
|
||||
Err(AxumErrorResponse::not_implemented())
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, utoipa::ToSchema)]
|
||||
struct LayerAssignmentsResponse {
|
||||
pub status: Option<TopologyRequestStatus>,
|
||||
|
||||
pub assignments: RewardedSetResponse,
|
||||
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, utoipa::ToSchema)]
|
||||
struct TopologyResponse {
|
||||
pub status: Option<TopologyRequestStatus>,
|
||||
|
||||
payload: Vec<u8>,
|
||||
payload_format: Option<PayloadFormat>,
|
||||
payload_signature: Option<Vec<u8>>,
|
||||
|
||||
current_topology_hash: Option<Vec<u8>>,
|
||||
topology_signature: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema, utoipa::ToSchema)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum TopologyRequestStatus {
|
||||
NoUpdates,
|
||||
Fresh(Interval),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::time::Duration;
|
||||
|
||||
use axum_test::TestServer;
|
||||
use nym_topology::NymTopology;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use crate::support::http::topology_cache::Epoch;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn build_test_topology_cache() -> TopologyCache {
|
||||
|
||||
let current_epoch = Epoch {
|
||||
id: 123,
|
||||
current_epoch_start: OffsetDateTime::now_utc(),
|
||||
epoch_length: Duration::from_secs(120),
|
||||
};
|
||||
|
||||
let topology = NymTopology::default();
|
||||
|
||||
TopologyCache::new(current_epoch, topology);
|
||||
todo!();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_topology_basic() -> Result<(), Box<dyn ::std::error::Error>> {
|
||||
let state = Arc::new(build_test_topology_cache());
|
||||
let app = topology_routes().with_state(state);
|
||||
|
||||
let server = TestServer::new(app)?;
|
||||
|
||||
let response = server
|
||||
.get(&"/layer_assignments")
|
||||
.await;
|
||||
|
||||
response.assert_text("hello!");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -25,11 +25,11 @@ use crate::nym_nodes::handlers::unstable::semi_skimmed::nodes_expanded;
|
||||
use crate::nym_nodes::handlers::unstable::skimmed::{
|
||||
entry_gateways_basic_active, entry_gateways_basic_all, exit_gateways_basic_active,
|
||||
exit_gateways_basic_all, mixnodes_basic_active, mixnodes_basic_all, nodes_basic_active,
|
||||
nodes_basic_all,
|
||||
nodes_basic_all, nodes_basic_batch,
|
||||
};
|
||||
use crate::support::http::helpers::PaginationRequest;
|
||||
use crate::support::http::state::AppState;
|
||||
use axum::routing::get;
|
||||
use axum::routing::{get, post};
|
||||
use axum::Router;
|
||||
use nym_api_requests::nym_nodes::NodeRoleQueryParam;
|
||||
use serde::Deserialize;
|
||||
@@ -47,6 +47,7 @@ pub(crate) fn nym_node_routes_unstable() -> Router<AppState> {
|
||||
"/skimmed",
|
||||
Router::new()
|
||||
.route("/", get(nodes_basic_all))
|
||||
.route("batch", post(nodes_basic_batch))
|
||||
.route("/active", get(nodes_basic_active))
|
||||
.nest(
|
||||
"/mixnodes",
|
||||
|
||||
@@ -25,6 +25,7 @@ use tracing::trace;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub type PaginatedSkimmedNodes = AxumResult<Json<PaginatedCachedNodesResponse<SkimmedNode>>>;
|
||||
type SkimmedNodes = AxumResult<Json<CachedNodesResponse<SkimmedNode>>>;
|
||||
|
||||
/// Given all relevant caches, build part of response for JUST Nym Nodes
|
||||
fn build_nym_nodes_response<'a, NI>(
|
||||
@@ -196,7 +197,7 @@ where
|
||||
pub(super) async fn deprecated_gateways_basic(
|
||||
state: State<AppState>,
|
||||
query_params: Query<NodesParams>,
|
||||
) -> AxumResult<Json<CachedNodesResponse<SkimmedNode>>> {
|
||||
) -> SkimmedNodes {
|
||||
// 1. call '/v1/unstable/skimmed/entry-gateways/all'
|
||||
let all_gateways = entry_gateways_basic_all(state, query_params).await?;
|
||||
|
||||
@@ -223,7 +224,7 @@ pub(super) async fn deprecated_gateways_basic(
|
||||
pub(super) async fn deprecated_mixnodes_basic(
|
||||
state: State<AppState>,
|
||||
query_params: Query<NodesParams>,
|
||||
) -> AxumResult<Json<CachedNodesResponse<SkimmedNode>>> {
|
||||
) -> SkimmedNodes {
|
||||
// 1. call '/v1/unstable/nym-nodes/skimmed/mixnodes/active'
|
||||
let active_mixnodes = mixnodes_basic_active(state, query_params).await?;
|
||||
|
||||
@@ -239,7 +240,7 @@ async fn nodes_basic(
|
||||
state: State<AppState>,
|
||||
Query(_query_params): Query<NodesParams>,
|
||||
active_only: bool,
|
||||
) -> PaginatedSkimmedNodes {
|
||||
) -> SkimmedNodes {
|
||||
// unfortunately we have to build the response semi-manually here as we need to add two sources of legacy nodes
|
||||
|
||||
// 1. grab all relevant described nym-nodes
|
||||
@@ -281,10 +282,10 @@ async fn nodes_basic(
|
||||
legacy_gateways.timestamp(),
|
||||
]);
|
||||
|
||||
Ok(Json(PaginatedCachedNodesResponse::new_full(
|
||||
Ok(Json(CachedNodesResponse {
|
||||
refreshed_at,
|
||||
nodes,
|
||||
)))
|
||||
}))
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // not dead, used in OpenAPI docs
|
||||
@@ -329,6 +330,31 @@ pub(super) async fn nodes_basic_all(
|
||||
nodes_basic(state, Query(query_params.into()), false).await
|
||||
}
|
||||
|
||||
/// Post request handler taking a json array of NodeId (u32) values and returning descriptors for
|
||||
/// the provided NodeId values. A successful response will contain descriptors for all nodes
|
||||
/// associated with those node IDs available in the current full topology.
|
||||
///
|
||||
/// If a provided node ID is not present in the current topology there will be no descriptor for
|
||||
/// that node in the response.
|
||||
///
|
||||
/// If no node IDs are provided the response will contain no descriptors.
|
||||
#[utoipa::path(
|
||||
tag = "Unstable Nym Nodes batch by Node ID",
|
||||
get,
|
||||
params(NodesParamsWithRole),
|
||||
path = "batch",
|
||||
context_path = "/v1/unstable/nym-nodes/skimmed",
|
||||
responses(
|
||||
(status = 200, body = PaginatedCachedNodesResponseSchema)
|
||||
)
|
||||
)]
|
||||
pub(super) async fn nodes_basic_batch(
|
||||
state: State<AppState>,
|
||||
Query(query_params): Query<NodesParamsWithRole>,
|
||||
) -> SkimmedNodes {
|
||||
nodes_basic(state, Query(query_params.into()), false).await
|
||||
}
|
||||
|
||||
/// Return Nym Nodes and optionally legacy mixnodes/gateways (if `no-legacy` flag is not used)
|
||||
/// that are currently bonded and are in the **active set**
|
||||
#[utoipa::path(
|
||||
|
||||
@@ -23,6 +23,7 @@ use crate::support::config::Config;
|
||||
use crate::support::http::state::{
|
||||
AppState, ForcedRefresh, ShutdownHandles, TASK_MANAGER_TIMEOUT_S,
|
||||
};
|
||||
use crate::support::http::topology_cache::{Epoch, TopologyCache};
|
||||
use crate::support::http::RouterBuilder;
|
||||
use crate::support::nyxd;
|
||||
use crate::support::storage::runtime_migrations::m001_directory_services_v2_1::migrate_to_directory_services_v2_1;
|
||||
@@ -35,6 +36,7 @@ use anyhow::{bail, Context};
|
||||
use nym_config::defaults::NymNetworkDetails;
|
||||
use nym_sphinx::receiver::SphinxMessageReceiver;
|
||||
use nym_task::TaskManager;
|
||||
use nym_topology::NymTopology;
|
||||
use nym_validator_client::nyxd::Coin;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
@@ -133,8 +135,6 @@ async fn start_nym_api_tasks_axum(config: &Config) -> anyhow::Result<ShutdownHan
|
||||
let identity_keypair = config.base.storage_paths.load_identity()?;
|
||||
let identity_public_key = *identity_keypair.public_key();
|
||||
|
||||
let router = RouterBuilder::with_default_routes(config.network_monitor.enabled);
|
||||
|
||||
let nym_contract_cache_state = NymContractCache::new();
|
||||
let node_status_cache_state = NodeStatusCache::new();
|
||||
let mix_denom = network_details.network.chain_details.mix_denom.base.clone();
|
||||
@@ -190,7 +190,16 @@ async fn start_nym_api_tasks_axum(config: &Config) -> anyhow::Result<ShutdownHan
|
||||
};
|
||||
|
||||
ecash_state.spawn_background_cleaner();
|
||||
let router = router.with_state(AppState {
|
||||
|
||||
|
||||
let epoch = Epoch::from(nym_contract_cache_state.current_interval().await.take());
|
||||
let topology = {
|
||||
todo!("cannot proceed without implementing this.");
|
||||
NymTopology::default()
|
||||
};
|
||||
let topology_cache = TopologyCache::new(epoch, topology);
|
||||
|
||||
let state = AppState {
|
||||
forced_refresh: ForcedRefresh::new(
|
||||
config.topology_cacher.debug.node_describe_allow_illegal_ips,
|
||||
),
|
||||
@@ -203,7 +212,11 @@ async fn start_nym_api_tasks_axum(config: &Config) -> anyhow::Result<ShutdownHan
|
||||
node_info_cache,
|
||||
api_status: ApiStatusState::new(signer_information),
|
||||
ecash_state: Arc::new(ecash_state),
|
||||
});
|
||||
topology_cache: Arc::new(topology_cache)
|
||||
};
|
||||
|
||||
let router = RouterBuilder::with_default_routes(&state, config.network_monitor.enabled);
|
||||
let router = router.with_state(state);
|
||||
|
||||
// start note describe cache refresher
|
||||
// we should be doing the below, but can't due to our current startup structure
|
||||
|
||||
@@ -6,6 +6,7 @@ pub(crate) mod openapi;
|
||||
pub(crate) mod router;
|
||||
pub(crate) mod state;
|
||||
mod unstable_routes;
|
||||
pub(crate) mod topology_cache;
|
||||
|
||||
pub(crate) use router::RouterBuilder;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::node_status_api::handlers::status_routes;
|
||||
use crate::nym_contract_cache::handlers::nym_contract_cache_routes;
|
||||
use crate::nym_nodes::handlers::legacy::legacy_nym_node_routes;
|
||||
use crate::nym_nodes::handlers::nym_node_routes;
|
||||
use crate::nym_nodes::handlers::topology::topology_routes;
|
||||
use crate::status;
|
||||
use crate::support::http::openapi::ApiDoc;
|
||||
use crate::support::http::state::AppState;
|
||||
@@ -38,7 +39,7 @@ pub(crate) struct RouterBuilder {
|
||||
impl RouterBuilder {
|
||||
/// All routes should be, if possible, added here. Exceptions are e.g.
|
||||
/// routes which are added conditionally in other places based on some `if`.
|
||||
pub(crate) fn with_default_routes(network_monitor: bool) -> Self {
|
||||
pub(crate) fn with_default_routes(state: &AppState, network_monitor: bool) -> Self {
|
||||
// https://docs.rs/tower-http/0.1.1/tower_http/trace/index.html
|
||||
// TODO rocket use tracing instead of env_logger
|
||||
// https://github.com/tokio-rs/axum/blob/main/examples/tracing-aka-logging/src/main.rs
|
||||
@@ -64,7 +65,9 @@ impl RouterBuilder {
|
||||
.nest("/api-status", status::handlers::api_status_routes())
|
||||
.nest("/nym-nodes", nym_node_routes())
|
||||
.nest("/ecash", ecash_routes())
|
||||
.nest("/unstable", unstable_routes()), // CORS layer needs to be "outside" of routes
|
||||
.nest("/unstable", unstable_routes())
|
||||
.nest("/topology", topology_routes().with_state(state.topology_cache.clone())),
|
||||
// CORS layer needs to be "outside" of routes
|
||||
);
|
||||
|
||||
Self {
|
||||
|
||||
@@ -12,6 +12,7 @@ use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use crate::status::ApiStatusState;
|
||||
use crate::support::caching::cache::SharedCache;
|
||||
use crate::support::caching::Cache;
|
||||
use crate::support::http::topology_cache::TopologyCache;
|
||||
use crate::support::storage;
|
||||
use axum::extract::FromRef;
|
||||
use nym_api_requests::models::{GatewayBondAnnotated, MixNodeBondAnnotated, NodeAnnotation};
|
||||
@@ -87,6 +88,7 @@ pub(crate) struct AppState {
|
||||
pub(crate) api_status: ApiStatusState,
|
||||
// todo: refactor it into inner: Arc<EcashStateInner>
|
||||
pub(crate) ecash_state: Arc<EcashState>,
|
||||
pub(crate) topology_cache: Arc<TopologyCache>
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for ApiStatusState {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#![warn(missing_docs)]
|
||||
#![warn(rustdoc::missing_crate_level_docs)]
|
||||
|
||||
|
||||
use std::collections::HashMap;
|
||||
use nym_topology::NymTopology;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use nym_mixnet_contract_common::{EpochId, Interval};
|
||||
use std::time::Duration;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
pub struct Epoch {
|
||||
pub id: EpochId,
|
||||
pub current_epoch_start: OffsetDateTime,
|
||||
pub epoch_length: Duration,
|
||||
}
|
||||
|
||||
impl From<Interval> for Epoch {
|
||||
fn from(value: Interval) -> Self {
|
||||
Self {
|
||||
id: value.current_epoch_id(),
|
||||
current_epoch_start: value.current_epoch_start(),
|
||||
epoch_length: value.epoch_length(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Format for
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema, utoipa::ToSchema)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub(crate) enum PayloadFormat {
|
||||
Json,
|
||||
BitCode,
|
||||
}
|
||||
|
||||
pub(crate) struct TopologyCache {
|
||||
current_epoch: Epoch,
|
||||
formats: HashMap<PayloadFormat, SerializedTopology>,
|
||||
cached: NymTopology,
|
||||
hash: Option<Vec<u8>>,
|
||||
signature: Option<Vec<u8>>
|
||||
}
|
||||
|
||||
pub(crate) struct SerializedTopology{
|
||||
bytes: Vec<u8>,
|
||||
signature: Vec<u8>,
|
||||
}
|
||||
|
||||
|
||||
impl TopologyCache {
|
||||
pub fn new(current_epoch: Epoch, initial: NymTopology) -> Self {
|
||||
Self {
|
||||
current_epoch,
|
||||
formats: HashMap::new(),
|
||||
cached: initial,
|
||||
hash: None,
|
||||
signature: None
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user