Skip to content

Commit

Permalink
order events
Browse files Browse the repository at this point in the history
  • Loading branch information
mmtftr committed Mar 4, 2025
1 parent db9ae74 commit 11ada57
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 22 deletions.
18 changes: 12 additions & 6 deletions core/src/states/kickoff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use super::{
Owner,
};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum KickoffEvent {
Challenged,
WatchtowerChallengeSent {
Expand Down Expand Up @@ -72,12 +72,12 @@ impl<T: Owner> BlockMatcher for KickoffStateMachine<T> {
self.matchers
.iter()
.filter_map(|(matcher, kickoff_event)| {
if matcher.matches(block) {
Some(kickoff_event.clone())
} else {
None
}
matcher.matches(block).map(|ord| (ord, kickoff_event))
})
.min()
.map(|(_, kickoff_event)| kickoff_event)
.into_iter()
.cloned()
.collect()
}
}
Expand Down Expand Up @@ -126,6 +126,12 @@ impl<T: Owner> KickoffStateMachine<T> {
) {
tracing::debug!(?self.kickoff_id, "Dispatching event {:?}", evt);
self.dirty = true;

// Remove the matcher corresponding to the event.
if let Some((matcher, _)) = self.matchers.iter().find(|(_, ev)| ev == &evt) {
let matcher = matcher.clone();
self.matchers.remove(&matcher);
}
}

async fn check_time_to_send_asserts(&mut self, context: &mut StateContext<T>) {
Expand Down
54 changes: 45 additions & 9 deletions core/src/states/matcher.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use std::cmp::Ordering;

use super::block_cache::BlockCache;
use bitcoin::{OutPoint, Txid};

pub(crate) trait BlockMatcher {
type StateEvent;

fn match_block(&self, block: &super::block_cache::BlockCache) -> Vec<Self::StateEvent>;
fn match_block(& self, block: &super::block_cache::BlockCache) -> Vec<Self::StateEvent>;
}

// Matcher for state machines to define what they're interested in
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum Matcher {
SentTx(Txid),
SpentUtxo(OutPoint),
Expand All @@ -18,16 +20,50 @@ pub enum Matcher {
BlockHeight(u32),
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MatcherOrd {
TxIndex(usize),
BlockHeight,
}

impl PartialOrd for MatcherOrd {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self, other) {
(MatcherOrd::TxIndex(a), MatcherOrd::TxIndex(b)) => a.partial_cmp(b),
(MatcherOrd::BlockHeight, MatcherOrd::BlockHeight) => Some(Ordering::Equal),
(MatcherOrd::BlockHeight, _) => Some(Ordering::Less),
(_, MatcherOrd::BlockHeight) => Some(Ordering::Greater),
}
}
}

impl Ord for MatcherOrd {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other)
.expect("partial_cmp always returns Some")
}
}

impl Matcher {
// TODO: sort by matched tx index
pub fn matches(&self, block: &BlockCache) -> bool {
pub fn matches(&self, block: &BlockCache) -> Option<MatcherOrd> {
match self {
Matcher::SentTx(txid) => block.contains_txid(txid),
Matcher::SpentUtxo(outpoint) => block.is_utxo_spent(outpoint),
Matcher::BlockHeight(height) => *height <= block.block_height,
Matcher::SpentUtxoButNotTimeout(outpoint, txid) => {
block.is_utxo_spent(outpoint) && !block.contains_txid(txid)
Matcher::SentTx(txid) if block.contains_txid(txid) => Some(MatcherOrd::TxIndex(
block.txids.get(txid).expect("txid is in cache").clone(),
)),
Matcher::SpentUtxo(outpoint) if (block.is_utxo_spent(outpoint)) => Some(
MatcherOrd::TxIndex(*block.spent_utxos.get(outpoint).expect("utxo is in cache")),
),
Matcher::BlockHeight(height) if *height <= block.block_height => {
Some(MatcherOrd::BlockHeight)
}
Matcher::SpentUtxoButNotTimeout(outpoint, txid)
if block.is_utxo_spent(outpoint) && !block.contains_txid(txid) =>
{
Some(MatcherOrd::TxIndex(
*block.spent_utxos.get(outpoint).expect("utxo is in cache"),
))
}
_ => None,
}
}
}
23 changes: 16 additions & 7 deletions core/src/states/round.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use eyre::Context;
use statig::prelude::*;
use std::collections::{HashMap, HashSet};
use std::{
collections::{HashMap, HashSet},
ops::DerefMut,
};

use crate::{
builder::{
Expand All @@ -17,7 +20,7 @@ use super::{
Owner,
};

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum RoundEvent {
KickoffUtxoUsed { kickoff_idx: usize },
ReadyToReimburseSent { round_idx: u32 },
Expand All @@ -40,12 +43,12 @@ impl<T: Owner> BlockMatcher for RoundStateMachine<T> {
self.matchers
.iter()
.filter_map(|(matcher, round_event)| {
if matcher.matches(block) {
Some(round_event.clone())
} else {
None
}
matcher.matches(block).map(|ord| (ord, round_event))
})
.min()
.map(|(_, round_event)| round_event)
.into_iter()
.cloned()
.collect()
}
}
Expand Down Expand Up @@ -100,6 +103,12 @@ impl<T: Owner> RoundStateMachine<T> {
) {
tracing::debug!(?self.operator_data, ?self.operator_idx, "Dispatching event {:?}", evt);
self.dirty = true;

// Remove the matcher corresponding to the event.
if let Some((matcher, _)) = self.matchers.iter().find(|(_, ev)| ev == &evt) {
let matcher = matcher.clone();
self.matchers.remove(&matcher);
}
}

#[state(entry_action = "on_initial_collateral_entry")]
Expand Down

0 comments on commit 11ada57

Please sign in to comment.