1#![warn(missing_docs)]
16#![warn(unused_crate_dependencies)]
17
18use error::GrpcError;
19use massa_models::slot::Slot;
20use massa_proto_rs::massa::model::v1 as grpc_model;
21use std::hash::Hash;
22use tonic_health as _;
23use tonic_reflection as _;
24use tonic_web as _;
25
26#[cfg(feature = "execution-trace")]
27use serde_json as _;
28
29pub mod config;
31pub mod error;
33pub mod handler;
35pub mod private;
37pub mod public;
39pub mod server;
41pub mod stream;
43
44#[cfg(test)]
45pub mod tests;
47
48#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
50pub struct SlotRange {
51 start_slot: Option<Slot>,
53 end_slot: Option<Slot>,
55}
56
57impl SlotRange {
58 pub fn check(&self) -> Result<(), GrpcError> {
60 match (self.start_slot, self.end_slot) {
61 (None, None) => Err(GrpcError::InvalidArgument(
62 "Invalid slot range: both start slot and end slot are empty".to_string(),
63 )),
64 (Some(s_slot), Some(e_slot)) if s_slot > e_slot => {
65 Err(GrpcError::InvalidArgument(format!(
66 "Invalid slot range: start slot {} is greater than end slot {}",
67 s_slot, e_slot
68 )))
69 }
70 (Some(s_slot), Some(e_slot)) if e_slot < s_slot => {
71 Err(GrpcError::InvalidArgument(format!(
72 "Invalid slot range: end slot {} is lower to start slot {}",
73 s_slot, e_slot
74 )))
75 }
76 (Some(s_slot), Some(e_slot)) if s_slot == e_slot => {
77 Err(GrpcError::InvalidArgument(format!(
78 "Invalid slot range: start slot {} is equal to end slot {}",
79 s_slot, e_slot
80 )))
81 }
82 _ => Ok(()),
83 }
84 }
85}
86
87#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
89struct SlotDraw {
90 slot: Option<Slot>,
92 block_producer: Option<String>,
94 endorsement_draws: Vec<EndorsementDraw>,
96}
97
98#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
100struct EndorsementDraw {
101 index: u64,
103 producer: String,
105}
106
107impl From<SlotDraw> for grpc_model::SlotDraw {
108 fn from(value: SlotDraw) -> Self {
109 grpc_model::SlotDraw {
110 slot: value.slot.map(Into::into),
111 block_producer: value.block_producer,
112 endorsement_draws: value
113 .endorsement_draws
114 .into_iter()
115 .map(Into::into)
116 .collect(),
117 }
118 }
119}
120
121impl From<EndorsementDraw> for grpc_model::EndorsementDraw {
122 fn from(value: EndorsementDraw) -> Self {
123 grpc_model::EndorsementDraw {
124 index: value.index,
125 producer: value.producer,
126 }
127 }
128}