Skip to content

Commit

Permalink
feat(fragments-endpoints): Add /fragments and /fragments/statuses com…
Browse files Browse the repository at this point in the history
…patibility endpoints
  • Loading branch information
Felipe Rosa committed Nov 14, 2023
1 parent 0f35c9b commit b7c84c5
Show file tree
Hide file tree
Showing 10 changed files with 261 additions and 2 deletions.
35 changes: 35 additions & 0 deletions catalyst-gateway/bin/src/service/api/fragments/index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Implementation of the GET /fragments endpoint
use poem_extensions::{response, UniResponse::T200};
use poem_openapi::payload::Json;

use crate::service::common::{
objects::{
fragments_batch::FragmentsBatch, fragments_processing_summary::FragmentsProcessingSummary,
},
responses::{
resp_2xx::OK,
resp_5xx::{ServerError, ServiceUnavailable},
},
};

/// All responses
pub(crate) type AllResponses = response! {
200: OK<Json<FragmentsProcessingSummary>>,
500: ServerError,
503: ServiceUnavailable,
};

/// # GET /fragments
///
/// Process a fragments batch.
///
/// ## Responses
///
/// * 200 No Content - Service is OK and can keep running.
/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible
/// but unlikely)
/// * 503 Service Unavailable - Service is possibly not running reliably.
pub(crate) async fn endpoint(_fragments_batch: FragmentsBatch) -> AllResponses {
T200(OK(Json(FragmentsProcessingSummary::default())))
}
40 changes: 40 additions & 0 deletions catalyst-gateway/bin/src/service/api/fragments/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//! Fragment endpoints
mod index;
mod statuses;

use poem_openapi::{param::Query, payload::Json, OpenApi};

use self::statuses::FragmentIds;
use crate::service::common::{objects::fragments_batch::FragmentsBatch, tags::ApiTags};

/// All Responses
pub(crate) struct FragmentsApi;

#[OpenApi(prefix_path = "/v1/fragments", tag = "ApiTags::Fragments")]
impl FragmentsApi {
/// Process fragments
///
/// Posts a fragments batch to be processed.
#[oai(path = "/", method = "post", operation_id = "fragments")]
async fn index(
&self,
/// Batch of fragments to be processed.
Json(fragments_batch): Json<FragmentsBatch>,
) -> index::AllResponses {
index::endpoint(fragments_batch).await
}

/// Get Fragment Statuses
///
/// Get statuses of the fragments with the given ids.
#[oai(path = "/statuses", method = "get", operation_id = "fragmentsStatuses")]
async fn statuses(
&self,
/// Comma-separated list of fragment ids for which the statuses will
/// be retrieved.
Query(fragment_ids): Query<FragmentIds>,
) -> statuses::AllResponses {
statuses::endpoint(fragment_ids).await
}
}
38 changes: 38 additions & 0 deletions catalyst-gateway/bin/src/service/api/fragments/statuses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//! Implementation of the GET /fragments/statuses endpoint
use std::collections::HashMap;

use poem_extensions::{response, UniResponse::T200};
use poem_openapi::payload::Json;

use crate::service::common::{
objects::fragment_status::FragmentStatus,
responses::{
resp_2xx::OK,
resp_5xx::{ServerError, ServiceUnavailable},
},
};

#[derive(poem_openapi::NewType)]
pub(crate) struct FragmentIds(String);

/// All responses
pub(crate) type AllResponses = response! {
200: OK<Json<HashMap<String, FragmentStatus>>>,
500: ServerError,
503: ServiceUnavailable,
};

/// # GET /fragments/statuses
///
/// Get fragments statuses endpoint.
///
/// ## Responses
///
/// * 200 Fragments Statuses - Statuses of the fragments by id.
/// * 500 Server Error - If anything within this function fails unexpectedly. (Possible
/// but unlikely)
/// * 503 Service Unavailable - Service is possibly not running reliably.
pub(crate) async fn endpoint(_fragment_ids: FragmentIds) -> AllResponses {
T200(OK(Json(HashMap::new())))
}
23 changes: 21 additions & 2 deletions catalyst-gateway/bin/src/service/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ use test_endpoints::TestApi;
use v0::V0Api;
use v1::V1Api;

use self::fragments::FragmentsApi;
use crate::settings::API_URL_PREFIX;

mod fragments;
mod health;
mod registration;
mod test_endpoints;
Expand Down Expand Up @@ -63,9 +65,26 @@ const TERMS_OF_SERVICE: &str =
/// Create the `OpenAPI` definition
pub(crate) fn mk_api(
hosts: Vec<String>,
) -> OpenApiService<(TestApi, HealthApi, RegistrationApi, V0Api, V1Api), ()> {
) -> OpenApiService<
(
TestApi,
HealthApi,
RegistrationApi,
V0Api,
V1Api,
FragmentsApi,
),
(),
> {
let mut service = OpenApiService::new(
(TestApi, HealthApi, RegistrationApi, V0Api, V1Api),
(
TestApi,
HealthApi,
RegistrationApi,
V0Api,
V1Api,
FragmentsApi,
),
API_TITLE,
API_VERSION,
)
Expand Down
28 changes: 28 additions & 0 deletions catalyst-gateway/bin/src/service/common/objects/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use poem_openapi::{types::Example, NewType, Object};

#[derive(NewType)]
/// Epoch number.
pub(crate) struct Epoch(pub u32);

#[derive(NewType)]
/// Slot number.
pub(crate) struct Slot(pub u32);

#[derive(Object)]
#[oai(example = true)]
/// Block time defined as the pair (epoch, slot).
pub(crate) struct BlockDate {
/// Block's epoch.
pub epoch: Epoch,
/// Block's slot number.
pub slot_id: Slot,
}

impl Example for BlockDate {
fn example() -> Self {
Self {
epoch: Epoch(1),
slot_id: Slot(5),
}
}
}
50 changes: 50 additions & 0 deletions catalyst-gateway/bin/src/service/common/objects/fragment_status.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use poem_openapi::{types::Example, Object, Union};

use crate::service::common::objects::{block::BlockDate, hash::Hash};

#[derive(Object)]
#[oai(example = false)]
/// Fragment is pending.
pub(crate) struct StatusPending;

#[derive(Object)]
#[oai(example = true)]
/// Fragment was rejected.
pub(crate) struct StatusRejected {
/// Reason the fragment was rejected.
pub reason: String,
}

impl Example for StatusRejected {
fn example() -> Self {
Self {
reason: "Transaction malformed".to_string(),
}
}
}

#[derive(Object)]
#[oai(example = true)]
/// Fragment is included in a block.
pub(crate) struct StatusInABlock {
pub date: BlockDate,
pub hash: Hash,
}

impl Example for StatusInABlock {
fn example() -> Self {
Self {
date: BlockDate::example(),
hash: Hash::example(),
}
}
}

#[derive(Union)]
#[oai(one_of = true)]
/// Possible fragment statuses.
pub(crate) enum FragmentStatus {
Pending(StatusPending),
Rejected(StatusRejected),
InABlock(StatusInABlock),
}
26 changes: 26 additions & 0 deletions catalyst-gateway/bin/src/service/common/objects/fragments_batch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use poem_openapi::{types::Example, NewType, Object};
use serde::Deserialize;

#[derive(NewType, Deserialize)]
/// Hex-encoded fragment's bytes.
pub(crate) struct FragmentDef(String);

#[derive(Object, Deserialize)]
#[oai(example = true)]
/// Batch of hex-encoded fragments.
pub(crate) struct FragmentsBatch {
/// Fragments are processed sequentially. If this is true, processing is
/// stopped after the first error occurs.
pub fail_fast: bool,
/// Array of hex-encoded fragments bytes.
pub fragments: Vec<FragmentDef>,
}

impl Example for FragmentsBatch {
fn example() -> Self {
Self {
fail_fast: false,
fragments: vec![],
}
}
}
17 changes: 17 additions & 0 deletions catalyst-gateway/bin/src/service/common/objects/hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use poem_openapi::{types::Example, Object};

#[derive(Object)]
#[oai(example = true)]
/// Blake2b256 hash wrapper.
pub(crate) struct Hash {
/// Blake2b256 hash encoded in hex.
pub hash: String,
}

impl Example for Hash {
fn example() -> Self {
Self {
hash: "928b20366943e2afd11ebc0eae2e53a93bf177a4fcf35bcc64d503704e65e202".to_string(),
}
}
}
4 changes: 4 additions & 0 deletions catalyst-gateway/bin/src/service/common/objects/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
//! This module contains common and re-usable objects.
pub(crate) mod account_votes;
pub(crate) mod block;
pub(crate) mod delegate_public_key;
pub(crate) mod event_id;
pub(crate) mod fragment_status;
pub(crate) mod fragments_batch;
pub(crate) mod fragments_processing_summary;
pub(crate) mod hash;
pub(crate) mod stake_public_key;
pub(crate) mod voter_group_id;
pub(crate) mod voter_info;
Expand Down
2 changes: 2 additions & 0 deletions catalyst-gateway/bin/src/service/common/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use poem_openapi::Tags;
/// `OpenAPI` Tags
#[derive(Tags)]
pub(crate) enum ApiTags {
/// Fragment endpoints
Fragments,
/// Health Endpoints
Health,
/// Information relating to Voter Registration, Delegations and Calculated Voting
Expand Down

0 comments on commit b7c84c5

Please sign in to comment.