Files
de-mls/src/user_actor.rs
Ekaterina Broslavskaya 4ea1136012 chore: implement consensus mechanism (#43)
* chore: implement consensus mechanism

- Updated `Cargo.lock`
- Refactored `Cargo.toml`
- Enhanced `action_handlers.rs` to introduce a ban request feature, allowing users to send ban requests through Waku.
- Implemented a new consensus module to manage proposal and voting processes, including state transitions for steward epochs.
- Updated error handling in `error.rs` to accommodate new consensus-related errors.
- Refactored `group.rs` and `user_actor.rs` to integrate the new consensus logic and improve state management.
- Added tests for the consensus mechanism to ensure reliability and correctness of the voting process.

* chore: update dependencies and refactor code for clarity

* refactor: update voting mechanism and clean up user actor logic

- Changed the return type of `complete_voting_for_steward` to return a vector of messages instead of a boolean.
- Removed unused request types and their implementations related to proposal handling.
- Updated the `handle_steward_flow_per_epoch` function to reflect changes in the voting process and improved logging.
- Refactored tests to align with the new voting mechanism and ensure proper message handling.
- Enhanced consensus logic to better handle vote counting and state transitions.

* feat: implement real voting for all users

- Improved logging messages for clarity during WebSocket message handling.
- Added new serverless functions and shims for better integration with the frontend.
- Introduced new manifest files for server configuration and routing.
- Implemented initial setup for handling user votes and proposals in the consensus mechanism.
- Updated error handling to accommodate new user vote actions and related messages.

* consensus: update test

* Enhance steward state management and consensus mechanism

- Added detailed documentation in README for steward state management, including state definitions, transitions, and flow scenarios.
- Updated `WakuNode` connection logic to include a timeout for peer connections.
- Refactored message handling in `action_handlers.rs` to utilize new `AppMessage` structures for improved clarity.
- Enhanced error handling in `error.rs` to cover new scenarios related to consensus and state transitions.
- Updated tests to reflect changes in the consensus mechanism and steward flow, ensuring robustness and reliability.
- Improved state machine logic to handle edge cases and guarantee proper state transitions during steward epochs.

* Refactor

- Updated `WakuMessageToSend` constructor to accept a slice for `app_id`, improving memory efficiency.
- Enhanced error handling in `Group` struct to provide more descriptive error messages for invalid states.
- Added detailed documentation for new methods in `Group` and `User` structs, clarifying their functionality and usage.
- Refactored state machine logic to ensure proper transitions during steward epochs and voting processes.
- Improved test coverage for group state management and message processing, ensuring robustness in various scenarios.

* Update README for improved clarity and formatting

* fix: fix lint issues and updates test flow

* test: update user test
2025-09-10 16:42:43 +03:00

192 lines
4.6 KiB
Rust

use kameo::message::{Context, Message};
use waku_bindings::WakuMessage;
use ds::waku_actor::WakuMessageToSend;
use crate::{
consensus::ConsensusEvent,
error::UserError,
protos::messages::v1::BanRequest,
user::{User, UserAction},
};
impl Message<WakuMessage> for User {
type Reply = Result<UserAction, UserError>;
async fn handle(
&mut self,
msg: WakuMessage,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.process_waku_message(msg).await
}
}
pub struct CreateGroupRequest {
pub group_name: String,
pub is_creation: bool,
}
impl Message<CreateGroupRequest> for User {
type Reply = Result<(), UserError>;
async fn handle(
&mut self,
msg: CreateGroupRequest,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.create_group(&msg.group_name, msg.is_creation).await?;
Ok(())
}
}
pub struct StewardMessageRequest {
pub group_name: String,
}
impl Message<StewardMessageRequest> for User {
type Reply = Result<WakuMessageToSend, UserError>;
async fn handle(
&mut self,
msg: StewardMessageRequest,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.prepare_steward_msg(&msg.group_name).await
}
}
pub struct LeaveGroupRequest {
pub group_name: String,
}
impl Message<LeaveGroupRequest> for User {
type Reply = Result<(), UserError>;
async fn handle(
&mut self,
msg: LeaveGroupRequest,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.leave_group(&msg.group_name).await?;
Ok(())
}
}
pub struct SendGroupMessage {
pub message: Vec<u8>,
pub group_name: String,
}
impl Message<SendGroupMessage> for User {
type Reply = Result<WakuMessageToSend, UserError>;
async fn handle(
&mut self,
msg: SendGroupMessage,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.build_group_message(msg.message, &msg.group_name).await
}
}
pub struct BuildBanMessage {
pub ban_request: BanRequest,
pub group_name: String,
}
impl Message<BuildBanMessage> for User {
type Reply = Result<WakuMessageToSend, UserError>;
async fn handle(
&mut self,
msg: BuildBanMessage,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.process_ban_request(msg.ban_request, &msg.group_name)
.await
}
}
// New state machine message types
pub struct StartStewardEpochRequest {
pub group_name: String,
}
impl Message<StartStewardEpochRequest> for User {
type Reply = Result<usize, UserError>; // Returns number of proposals
async fn handle(
&mut self,
msg: StartStewardEpochRequest,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.start_steward_epoch(&msg.group_name).await
}
}
pub struct GetProposalsForStewardVotingRequest {
pub group_name: String,
}
impl Message<GetProposalsForStewardVotingRequest> for User {
type Reply = Result<UserAction, UserError>; // Returns proposal_id
async fn handle(
&mut self,
msg: GetProposalsForStewardVotingRequest,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
let (_, action) = self
.get_proposals_for_steward_voting(&msg.group_name)
.await?;
Ok(action)
}
}
pub struct UserVoteRequest {
pub group_name: String,
pub proposal_id: u32,
pub vote: bool,
}
impl Message<UserVoteRequest> for User {
type Reply = Result<Option<WakuMessageToSend>, UserError>;
async fn handle(
&mut self,
msg: UserVoteRequest,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
let action = self
.process_user_vote(msg.proposal_id, msg.vote, &msg.group_name)
.await?;
match action {
UserAction::SendToWaku(waku_msg) => Ok(Some(waku_msg)),
UserAction::DoNothing => Ok(None),
_ => Err(UserError::InvalidUserAction(
"Vote action must result in Waku message".to_string(),
)),
}
}
}
// Consensus event message handler
pub struct ConsensusEventMessage {
pub group_name: String,
pub event: ConsensusEvent,
}
impl Message<ConsensusEventMessage> for User {
type Reply = Result<Vec<WakuMessageToSend>, UserError>;
async fn handle(
&mut self,
msg: ConsensusEventMessage,
_ctx: Context<'_, Self, Self::Reply>,
) -> Self::Reply {
self.handle_consensus_event(&msg.group_name, msg.event)
.await
}
}