pub trait StateMachine:
Send
+ Sync
+ Clone {
type Command: Send + Sync + Clone;
type Response: Send + Sync + Clone;
type State: Send + Sync + Clone;
// Required methods
fn apply_command<'life0, 'async_trait>(
&'life0 mut self,
command: Self::Command,
) -> Pin<Box<dyn Future<Output = Self::Response> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn get_state(&self) -> Self::State;
fn set_state(&mut self, state: Self::State);
fn serialize_state(&self) -> Vec<u8> ⓘ;
fn deserialize_state(&mut self, data: &[u8]) -> Result<(), Box<dyn Error>>;
// Provided methods
fn apply_commands<'life0, 'async_trait>(
&'life0 mut self,
commands: Vec<Self::Command>,
) -> Pin<Box<dyn Future<Output = Vec<Self::Response>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait { ... }
fn is_deterministic(&self) -> bool { ... }
}Expand description
Re-export commonly used types for convenience Core trait for State Machine Replication in Rabia consensus.
This trait defines the interface that any state machine must implement to be used with the Rabia consensus protocol. The trait ensures that state machines are deterministic and can be safely replicated across multiple nodes.
§Example Implementation
use rabia_core::smr::StateMachine;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
#[derive(Clone, Serialize, Deserialize)]
pub struct CounterCommand {
pub operation: String, // "increment", "decrement", "get"
pub value: i64,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct CounterResponse {
pub value: i64,
pub success: bool,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct CounterState {
pub value: i64,
}
#[derive(Clone)]
pub struct CounterStateMachine {
state: CounterState,
}
#[async_trait]
impl StateMachine for CounterStateMachine {
type Command = CounterCommand;
type Response = CounterResponse;
type State = CounterState;
async fn apply_command(&mut self, command: Self::Command) -> Self::Response {
match command.operation.as_str() {
"increment" => {
self.state.value += command.value;
CounterResponse { value: self.state.value, success: true }
}
"decrement" => {
self.state.value -= command.value;
CounterResponse { value: self.state.value, success: true }
}
"get" => {
CounterResponse { value: self.state.value, success: true }
}
_ => CounterResponse { value: self.state.value, success: false }
}
}
fn get_state(&self) -> Self::State {
self.state.clone()
}
fn set_state(&mut self, state: Self::State) {
self.state = state;
}
fn serialize_state(&self) -> Vec<u8> {
bincode::serialize(&self.state).unwrap_or_default()
}
fn deserialize_state(&mut self, data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
self.state = bincode::deserialize(data)?;
Ok(())
}
}Required Associated Types§
Required Methods§
Sourcefn apply_command<'life0, 'async_trait>(
&'life0 mut self,
command: Self::Command,
) -> Pin<Box<dyn Future<Output = Self::Response> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn apply_command<'life0, 'async_trait>(
&'life0 mut self,
command: Self::Command,
) -> Pin<Box<dyn Future<Output = Self::Response> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Sourcefn get_state(&self) -> Self::State
fn get_state(&self) -> Self::State
Get the current state of the state machine.
This method should return a snapshot of the current state that can be used for state transfer or debugging.
Sourcefn set_state(&mut self, state: Self::State)
fn set_state(&mut self, state: Self::State)
Set the state of the state machine.
This method is used during state transfer operations to restore the state machine to a specific state.
§Arguments
state- The state to restore
Sourcefn serialize_state(&self) -> Vec<u8> ⓘ
fn serialize_state(&self) -> Vec<u8> ⓘ
Serialize the current state to bytes.
This method is used for persistence and state transfer operations. The serialized data should contain all information necessary to restore the state machine to its current state.
§Returns
A byte vector containing the serialized state
Provided Methods§
Sourcefn apply_commands<'life0, 'async_trait>(
&'life0 mut self,
commands: Vec<Self::Command>,
) -> Pin<Box<dyn Future<Output = Vec<Self::Response>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn apply_commands<'life0, 'async_trait>(
&'life0 mut self,
commands: Vec<Self::Command>,
) -> Pin<Box<dyn Future<Output = Vec<Self::Response>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Sourcefn is_deterministic(&self) -> bool
fn is_deterministic(&self) -> bool
Check if this state machine is deterministic.
All state machines used with Rabia consensus MUST be deterministic. This method is provided for validation and debugging purposes.
§Returns
true if the state machine is deterministic (should always return true)
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".