diff --git a/nodes/api-common/src/paths.rs b/nodes/api-common/src/paths.rs index a87c52428..9b5ab58dc 100644 --- a/nodes/api-common/src/paths.rs +++ b/nodes/api-common/src/paths.rs @@ -1,6 +1,7 @@ pub const MANTLE_METRICS: &str = "/mantle/metrics"; pub const MANTLE_STATUS: &str = "/mantle/status"; pub const MANTLE_SDP_DECLARATIONS: &str = "/mantle/sdp/declarations"; +pub const MANTLE_SDP_SNAPSHOT: &str = "/mantle/sdp/snapshot"; pub const MANTLE_GAS_PRICES: &str = "/mantle/gas-prices"; pub const CRYPTARCHIA_INFO: &str = "/cryptarchia/info"; pub const CRYPTARCHIA_HEADERS: &str = "/cryptarchia/headers"; diff --git a/nodes/node/binary/src/api/backend.rs b/nodes/node/binary/src/api/backend.rs index 547df1bca..cc7b4129c 100644 --- a/nodes/node/binary/src/api/backend.rs +++ b/nodes/node/binary/src/api/backend.rs @@ -46,8 +46,8 @@ use utoipa_swagger_ui::SwaggerUi; use super::handlers::{ add_tx, blend_info, block, block_events, blocks_range_stream, blocks_stream, cryptarchia_headers, cryptarchia_info, cryptarchia_lib_stream, dial_peer, get_gas_prices, - get_sdp_declarations, immutable_blocks, libp2p_info, mantle_metrics, mantle_status, - mempool_view, time_info, transaction, wallet, + get_sdp_declarations, get_sdp_snapshot, immutable_blocks, libp2p_info, mantle_metrics, + mantle_status, mempool_view, time_info, transaction, wallet, }; use crate::{ BlendBroadcastSettings, BlendService, TracingService, WalletService, @@ -311,6 +311,10 @@ where paths::MANTLE_SDP_DECLARATIONS, routing::get(get_sdp_declarations::), ) + .route( + paths::MANTLE_SDP_SNAPSHOT, + routing::get(get_sdp_snapshot::), + ) .route( paths::LEADER_CLAIM, routing::post(leader_claim::), diff --git a/nodes/node/binary/src/api/handlers.rs b/nodes/node/binary/src/api/handlers.rs index ca8895782..00aa4a699 100644 --- a/nodes/node/binary/src/api/handlers.rs +++ b/nodes/node/binary/src/api/handlers.rs @@ -1233,6 +1233,24 @@ where make_request_and_return_response!(mantle::get_sdp_declarations::(&handle)) } +#[utoipa::path( + get, + path = paths::MANTLE_SDP_SNAPSHOT, + responses( + (status = 200, description = "Get the SDP snapshot for the current epoch keyed by declaration id", body = std::collections::HashMap), + (status = 500, description = "Internal server error", body = String), + ) +)] +pub async fn get_sdp_snapshot( + State(handle): State>, +) -> Response +where + RuntimeServiceId: + Debug + Send + Sync + Display + 'static + AsServiceId>, +{ + make_request_and_return_response!(mantle::get_sdp_snapshot::(&handle)) +} + #[utoipa::path( post, path = paths::LEADER_CLAIM, diff --git a/nodes/node/binary/src/api/openapi.rs b/nodes/node/binary/src/api/openapi.rs index b519ae5db..d09bba646 100644 --- a/nodes/node/binary/src/api/openapi.rs +++ b/nodes/node/binary/src/api/openapi.rs @@ -21,6 +21,7 @@ use utoipa::OpenApi; crate::api::handlers::post_activity, crate::api::handlers::post_withdrawal, crate::api::handlers::get_sdp_declarations, + crate::api::handlers::get_sdp_snapshot, crate::api::handlers::leader_claim, crate::api::handlers::immutable_blocks, crate::api::handlers::block, diff --git a/services/api/src/http/mantle.rs b/services/api/src/http/mantle.rs index a8a0b9aee..28f0ec94f 100644 --- a/services/api/src/http/mantle.rs +++ b/services/api/src/http/mantle.rs @@ -923,3 +923,28 @@ where Ok(receiver.await?) } + +pub async fn get_sdp_snapshot( + handle: &overwatch::overwatch::handle::OverwatchHandle, +) -> Result, super::DynError> +where + RuntimeServiceId: Debug + + Send + + Sync + + Display + + 'static + + AsServiceId> + + 'static, +{ + let relay = handle.relay::>().await?; + let (sender, receiver) = oneshot::channel(); + + relay + .send(ConsensusMsg::GetSdpSnapshot { + reply_channel: sender, + }) + .await + .map_err(|(e, _)| e)?; + + Ok(receiver.await?) +} diff --git a/services/chain/chain-service/src/lib.rs b/services/chain/chain-service/src/lib.rs index 47d0e473d..d1457b2e9 100644 --- a/services/chain/chain-service/src/lib.rs +++ b/services/chain/chain-service/src/lib.rs @@ -143,9 +143,14 @@ pub enum ConsensusMsg { block_id: HeaderId, reply_channel: oneshot::Sender>, }, + /// Returns all declarations in the current SDP registry, not snapshot GetSdpDeclarations { reply_channel: oneshot::Sender>, }, + /// Returns the frozen SDP snapshot for the current epoch + GetSdpSnapshot { + reply_channel: oneshot::Sender>, + }, GetEpochState { slot: Slot, reply_channel: oneshot::Sender>, @@ -939,6 +944,28 @@ where error!("Could not send SDP declarations through channel"); }); } + ConsensusMsg::GetSdpSnapshot { reply_channel } => { + let tip = cryptarchia.tip(); + let declarations = cryptarchia + .ledger + .state(&tip) + .map(|ledger_state| { + ledger_state + .epoch_state() + .active_declarations + .iter() + .flat_map(|(_, declarations)| { + declarations + .iter() + .map(|(id, declaration)| (*id, declaration.clone())) + }) + .collect() + }) + .unwrap_or_default(); + reply_channel.send(declarations).unwrap_or_else(|_| { + error!("Could not send SDP snapshot through channel"); + }); + } ConsensusMsg::GetEpochState { slot, reply_channel,