liminal_protocol/lifecycle/admission/
observer.rs1use crate::wire::{
2 AttachEnvelope, BindingEpoch, DeliverySeq, DetachEnvelope, EnrollmentEnvelope, LeaveEnvelope,
3 ObserverBackpressure, ObserverBackpressureState, RecordAdmissionEnvelope,
4};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
12pub enum ObserverCheckedOperation {
13 Enrollment(EnrollmentEnvelope),
15 CredentialAttach(AttachEnvelope),
17 InitialDetach {
19 request: DetachEnvelope,
21 committed_binding_epoch: BindingEpoch,
23 },
24 Leave {
26 request: LeaveEnvelope,
28 prior_terminal_cell_exists: bool,
30 },
31 RecordAdmission(RecordAdmissionEnvelope),
33}
34
35#[derive(Clone, Copy, Debug, PartialEq, Eq)]
41pub struct ObserverFloorPermit {
42 observer_progress: DeliverySeq,
43 cap_floor: u128,
44}
45
46impl ObserverFloorPermit {
47 #[must_use]
49 pub const fn observer_progress(self) -> DeliverySeq {
50 self.observer_progress
51 }
52
53 #[must_use]
55 pub const fn cap_floor(self) -> u128 {
56 self.cap_floor
57 }
58}
59
60#[derive(Clone, Debug, PartialEq, Eq)]
62pub enum ObserverFloorDecision {
63 Eligible(ObserverFloorPermit),
65 Respond(ObserverBackpressure),
67}
68
69#[must_use]
76pub fn check_observer_floor(
77 operation: ObserverCheckedOperation,
78 observer_progress: DeliverySeq,
79 cap_floor: u128,
80) -> ObserverFloorDecision {
81 let observer_limit = u128::from(observer_progress) + 1;
82 if cap_floor <= observer_limit {
83 return ObserverFloorDecision::Eligible(ObserverFloorPermit {
84 observer_progress,
85 cap_floor,
86 });
87 }
88
89 let state = ObserverBackpressureState::initial(observer_progress);
90 let response = match operation {
91 ObserverCheckedOperation::Enrollment(request) => {
92 ObserverBackpressure::Enrollment { request, state }
93 }
94 ObserverCheckedOperation::CredentialAttach(request) => {
95 ObserverBackpressure::CredentialAttach { request, state }
96 }
97 ObserverCheckedOperation::InitialDetach {
98 request,
99 committed_binding_epoch,
100 } => ObserverBackpressure::Detach {
101 request,
102 committed_binding_epoch,
103 state,
104 },
105 ObserverCheckedOperation::Leave {
106 request,
107 prior_terminal_cell_exists,
108 } => ObserverBackpressure::Leave {
109 request,
110 state,
111 prior_terminal_cell_exists,
112 },
113 ObserverCheckedOperation::RecordAdmission(request) => {
114 ObserverBackpressure::RecordAdmission { request, state }
115 }
116 };
117 ObserverFloorDecision::Respond(response)
118}