pub struct GroupNode {
pub member_id: MemberId,
pub is_coordinator: bool,
pub group_id: GroupId,
pub current_epoch: u64,
pub last_transition_id: TransitionId,
pub pending_transition_id: TransitionId,
pub state: NodeState,
pub transition_state: TransitionState,
/* private fields */
}Expand description
GBP-layer node.
Owns the framing, AEAD, replay window, FSM and control plane.
Sub-protocol semantics live in their own crates and use this type plus a
Sealer for outbound traffic and on_wire + the resulting events for
inbound traffic.
Fields§
§member_id: MemberIdApplication-level member id.
is_coordinator: boolWhether this node currently holds the coordinator role.
group_id: GroupId16-byte group identifier.
current_epoch: u64Current epoch as observed by the GBP layer (the authoritative epoch lives in the underlying MLS group).
last_transition_id: TransitionIdLast applied transition_id.
pending_transition_id: TransitionIdPending transition_id (set during PREPARE / READY).
state: NodeStateNode FSM.
transition_state: TransitionStateTransition FSM.
Implementations§
Source§impl GroupNode
impl GroupNode
Sourcepub fn new(member_id: MemberId, group_id: GroupId) -> Self
pub fn new(member_id: MemberId, group_id: GroupId) -> Self
Builds a fresh node in the IDLE state.
Sourcepub fn bootstrap_as_creator(&mut self, epoch: u64)
pub fn bootstrap_as_creator(&mut self, epoch: u64)
Drives the node from IDLE to ACTIVE as a creator.
Sourcepub fn bootstrap_as_joiner(&mut self, epoch: u64, expected_first_tid: u32)
pub fn bootstrap_as_joiner(&mut self, epoch: u64, expected_first_tid: u32)
Drives the node from IDLE to ACTIVE as a joiner.
expected_first_tid lets the joiner pre-arm its pending transition
state so that the very next EXECUTE_TRANSITION (which will arrive
without a preceding PREPARE the joiner could decrypt — that PREPARE
was sealed under the pre-Welcome epoch) is accepted by
handle_control’s tid-validation matrix. Pass 0 if the joiner
recovered out-of-band and is already current.
Sourcepub fn drain_events(&mut self) -> Vec<Event>
pub fn drain_events(&mut self) -> Vec<Event>
Drains and returns all queued events.
Sourcepub fn member_stream_id(&self, base: u32) -> StreamId
pub fn member_stream_id(&self, base: u32) -> StreamId
Returns a sender-unique stream_id within the given base class.
This is used so that the receiver’s replay window does not conflate streams that originate from different members.
Sourcepub fn send_payload<S: Sealer>(
&mut self,
seal: &mut S,
target: MemberId,
stream_type: StreamType,
stream_id: StreamId,
flags: u16,
plaintext: &[u8],
) -> Result<OutboundFrame, NodeError>
pub fn send_payload<S: Sealer>( &mut self, seal: &mut S, target: MemberId, stream_type: StreamType, stream_id: StreamId, flags: u16, plaintext: &[u8], ) -> Result<OutboundFrame, NodeError>
Sends an opaque plaintext payload on the given stream.
Used by the sub-protocol clients: each one CBOR-encodes its message and forwards the resulting bytes here.
Sourcepub fn send_control<S: Sealer>(
&mut self,
seal: &mut S,
target: MemberId,
opcode: ControlOpcode,
transition_id: TransitionId,
request_id: u32,
args: Vec<u8>,
) -> Result<OutboundFrame, NodeError>
pub fn send_control<S: Sealer>( &mut self, seal: &mut S, target: MemberId, opcode: ControlOpcode, transition_id: TransitionId, request_id: u32, args: Vec<u8>, ) -> Result<OutboundFrame, NodeError>
Sends a control plane message on Stream 0. Wrapper around
GroupNode::send_payload.
Side effect: when the coordinator originates a PREPARE_TRANSITION,
it must locally adopt the same pending_transition_id so that the
inbound READY / EXECUTE validation matrix in handle_control lines
up. Without this, the coordinator never matches its own pending tid
against the remote READY frames it expects, and the handshake never
completes.
Sourcepub fn on_wire<S: Sealer>(
&mut self,
seal: &mut S,
wire: &[u8],
) -> Result<Vec<Event>, NodeError>
pub fn on_wire<S: Sealer>( &mut self, seal: &mut S, wire: &[u8], ) -> Result<Vec<Event>, NodeError>
Feeds wire bytes to the node.
Performs the §6.2 validation pipeline (version → group_id → epoch → payload_size → transition_id → replay), opens the AEAD payload and either:
- dispatches the parsed control message internally (for
StreamType::Control), or - surfaces an
Event::PayloadReceived(for application streams).
Returns every event that was produced as a result.
Sourcepub fn apply_transition(&mut self, tid: TransitionId)
pub fn apply_transition(&mut self, tid: TransitionId)
Applies a new epoch (called by the coordinator after
EXECUTE_TRANSITION).
Sourcepub fn trigger_resync(&mut self)
pub fn trigger_resync(&mut self)
Forces the node into the RESYNCING state.
Sourcepub fn check_timeouts(&mut self) -> Vec<Event>
pub fn check_timeouts(&mut self) -> Vec<Event>
Checks FSM deadlines and emits timeout events if any have expired.
Call this regularly from the application event loop (e.g. every 500 ms).
Returns the same events that would come from GroupNode::drain_events;
the caller may also drain events separately — this method does not
duplicate them.
Sourcepub fn note_coordinator_activity(&mut self)
pub fn note_coordinator_activity(&mut self)
Records that the coordinator was active right now.
Call this whenever the node receives a frame from the current
coordinator (e.g. PREPARE_TRANSITION, EXECUTE_TRANSITION,
CAPABILITIES_ADVERTISE with coordinator_claim). Resets the
coordinator-silence timer used to detect ERR_COORDINATOR_GONE.
Sourcepub fn claim_coordinator<S: Sealer>(
&mut self,
seal: &mut S,
target: MemberId,
) -> Result<OutboundFrame, NodeError>
pub fn claim_coordinator<S: Sealer>( &mut self, seal: &mut S, target: MemberId, ) -> Result<OutboundFrame, NodeError>
Claims the coordinator role by broadcasting CAPABILITIES_ADVERTISE
with coordinator_claim=true (gbp-control-plane §5.1).
Call this when Event::CoordinatorElectionNeeded fires and this
node has the lowest MemberId among currently active members. The
caller is responsible for delivering the returned frame to every group
member.
The args payload is the minimal CBOR map {0: true} encoding a
coordinator claim flag.
Auto Trait Implementations§
impl Freeze for GroupNode
impl RefUnwindSafe for GroupNode
impl Send for GroupNode
impl Sync for GroupNode
impl Unpin for GroupNode
impl UnsafeUnpin for GroupNode
impl UnwindSafe for GroupNode
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Declassify for T
impl<T> Declassify for T
type Declassified = T
fn declassify(self) -> T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more