Skip to content

Commit

Permalink
fix(states): dirty updating
Browse files Browse the repository at this point in the history
  • Loading branch information
mmtftr committed Feb 28, 2025
1 parent 51d6c97 commit 6d98184
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 16 deletions.
12 changes: 8 additions & 4 deletions core/src/states/kickoff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl<T: Owner> KickoffStateMachine<T> {
kickoff_height,
deposit_data,
matchers: HashMap::new(),
dirty: false,
dirty: true,
phantom: std::marker::PhantomData,
watchtower_challenges: HashMap::new(),
operator_asserts: HashMap::new(),
Expand All @@ -102,7 +102,7 @@ impl<T: Owner> KickoffStateMachine<T> {

#[state_machine(
initial = "State::kickoff_started()",
on_transition = "Self::on_transition",
on_dispatch = "Self::on_dispatch",
state(derive(Debug, Clone))
)]
impl<T: Owner> KickoffStateMachine<T> {
Expand All @@ -119,8 +119,12 @@ impl<T: Owner> KickoffStateMachine<T> {
}

#[action]
pub(crate) fn on_transition(&mut self, state_a: &State, state_b: &State) {
tracing::debug!(?self.kickoff_id, "Transitioning from {:?} to {:?}", state_a, state_b);
pub(crate) fn on_dispatch(
&mut self,
_state: StateOrSuperstate<'_, '_, Self>,
evt: &KickoffEvent,
) {
tracing::debug!(?self.kickoff_id, "Dispatching event {:?}", evt);
self.dirty = true;
}

Expand Down
55 changes: 47 additions & 8 deletions core/src/states/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ where
T: Owner,
for<'evt, 'ctx> M: IntoStateMachine<Event<'evt> = M::StateEvent, Context<'ctx> = context::StateContext<T>>
+ Send
+ BlockMatcher,
+ BlockMatcher
+ Clone,
M::State: awaitable::State<M> + 'static + Send,
for<'sub> M::Superstate<'sub>: awaitable::Superstate<M> + Send,
for<'evt> M::Event<'evt>: Send + Sync,
Expand Down Expand Up @@ -102,6 +103,16 @@ impl<T: Owner + 'static> StateManager<T> {
}
}

pub fn load_from_db(&mut self) -> Result<(), BridgeError> {
// TODO: implement
Ok(())
}

pub fn save_to_db(&self) -> Result<(), BridgeError> {
// TODO: implement
Ok(())
}

fn create_context(
handler: T,
db: Database,
Expand Down Expand Up @@ -162,7 +173,7 @@ impl<T: Owner + 'static> StateManager<T> {
}

/// Processes the block and moves all state machines forward in parallel.
/// The state machines are updated until they stabilize in their state (ie.
/// The state machines are updated until all of them stabilize in their state (ie.
/// the block does not generate any new events)
///
/// # Errors
Expand Down Expand Up @@ -190,12 +201,6 @@ impl<T: Owner + 'static> StateManager<T> {
// On each iteration, we'll update the changed machines until all machines
// stabilize in their state.
while !kickoff_futures.is_empty() || !round_futures.is_empty() {
if iterations > 50 {
return Err(BridgeError::Error(
"State machines did not stabilize after 50 iterations".into(),
));
}

// Execute all futures in parallel
let (kickoff_results, round_results) =
join(join_all(kickoff_futures), join_all(round_futures)).await;
Expand All @@ -221,10 +226,44 @@ impl<T: Owner + 'static> StateManager<T> {

// Append the newly generated state machines into the changed machines list
for ctx in kickoff_contexts.iter_mut().chain(round_contexts.iter_mut()) {
#[cfg(debug_assertions)]
for machine in &ctx.new_round_machines {
if !machine.dirty {
panic!("Round machine not dirty despite having been newly created: {:?}", machine.state());
}
}
for machine in &ctx.new_kickoff_machines {
if !machine.dirty {
panic!("Kickoff machine not dirty despite having been newly created: {:?}", machine.state());
}
}
changed_round_machines.extend(std::mem::take(&mut ctx.new_round_machines));
changed_kickoff_machines.extend(std::mem::take(&mut ctx.new_kickoff_machines));
}

if iterations > 50 {
return Err(BridgeError::Error(format!(
r#"{}/{} kickoff and {}/{} round state machines did not stabilize after 50 iterations, debug repr of changed machines:
---- Kickoff machines ----
{:?}
---- Round machines ----
{:?}
"#,
changed_kickoff_machines.len(),
final_kickoff_machines.len() + changed_kickoff_machines.len(),
changed_round_machines.len(),
final_round_machines.len() + changed_round_machines.len(),
changed_kickoff_machines
.iter()
.map(|m| m.state())
.collect::<Vec<_>>(),
changed_round_machines
.iter()
.map(|m| m.state())
.collect::<Vec<_>>(),
)));
}

// Reprocess changed machines and commit these futures to be handled
// in the next round If they're empty, we'll exit the loop.
let (finalized_kickoff_machines, new_kickoff_futures) =
Expand Down
8 changes: 4 additions & 4 deletions core/src/states/round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl<T: Owner> RoundStateMachine<T> {
matchers: HashMap::new(),
operator_data,
operator_idx,
dirty: false,
dirty: true,
phantom: std::marker::PhantomData,
}
}
Expand All @@ -65,7 +65,7 @@ use eyre::Report;

#[state_machine(
initial = "State::initial_collateral()",
on_transition = "Self::on_transition",
on_dispatch = "Self::on_dispatch",
state(derive(Debug, Clone))
)]
// TODO: Add exit conditions too (ex: burn connector spent on smth else)
Expand All @@ -83,8 +83,8 @@ impl<T: Owner> RoundStateMachine<T> {
}

#[action]
pub(crate) fn on_transition(&mut self, state_a: &State, state_b: &State) {
tracing::debug!(?self.operator_data, ?self.operator_idx, "Transitioning from {:?} to {:?}", state_a, state_b);
pub(crate) fn on_dispatch(&mut self, _state: StateOrSuperstate<'_, '_, Self>, evt: &RoundEvent) {
tracing::debug!(?self.operator_data, ?self.operator_idx, "Dispatching event {:?}", evt);
self.dirty = true;
}

Expand Down

0 comments on commit 6d98184

Please sign in to comment.