diff --git a/crates/chaff-machines/src/constant.rs b/crates/chaff-machines/src/constant.rs index 16744f7..3e05e5c 100644 --- a/crates/chaff-machines/src/constant.rs +++ b/crates/chaff-machines/src/constant.rs @@ -20,37 +20,45 @@ use chaff::{ #[must_use] #[expect(clippy::expect_used)] pub fn construct() -> Machine { - let hundred_ms: Distr = Duration::from_millis(100) + let hundred_ms: Distr = Duration::from_millis(100).try_into().expect("valid distr"); + let long_delay: Distr = Duration::from_micros(u64::MAX) .try_into() - .expect("constant shouldn't cause validation issue"); - let max: Distr = Duration::from_nanos(u64::MAX) - .try_into() - .expect("constant shouldn't cause validation issue"); - let zero: Distr = Duration::ZERO - .try_into() - .expect("constant shouldn't cause validation issue"); + .expect("valid distr"); + let zero: Distr = Duration::ZERO.try_into().expect("valid distr"); machine! { queues: [Some(1), Some(1), Some(1)], budget: Absolute(500), state init { - action: IntegratorAction::BlockOutgoing(max), + action: IntegratorAction::BlockOutgoing(long_delay), // block immediately transitions: [ - Event::SendNormal => init, - Event::SendBlocked => schedule_release, - Event::ReceiveNormal => schedule_release, + Event::SendBlocked => schedule_release, // first blocked packet ], }, - state do_block { + state schedule_release { + // schedule a release with a 100ms delay action: FrameworkAction::schedule( - IntegratorAction::BlockOutgoing(max), - 1, - zero, + IntegratorAction::ReleaseBlock, + 0, + hundred_ms, ), transitions: [ - Event::QueueFilled(1) => schedule_release, + // since we scheduled on a 1 capacity queue, this transition should + // happen immediately + Event::QueueFilled(0) => blocked, ], }, + state blocked { + transitions: [ + Event::QueueEmpty(0) => send_decoy, // no real packet sent + Event::SendBlocked => wait, // real packet sent + ] + }, + state wait { + transitions: [ + Event::QueueEmpty(0) => do_block, // wait until release happens + ] + }, state send_decoy { action: FrameworkAction::schedule( IntegratorAction::SendDecoy, @@ -58,30 +66,22 @@ pub fn construct() -> Machine { zero, ), transitions: [ + // similar trick to schedule_release, this time used to do two actions + // in quick succession Event::QueueFilled(2) => do_block, ] }, - state schedule_release { + state do_block { action: FrameworkAction::schedule( - IntegratorAction::ReleaseBlock, - 0, - hundred_ms, + IntegratorAction::BlockOutgoing(long_delay), + 1, + zero, ), transitions: [ - Event::QueueFilled(0) => blocked, + // similar trick to send_decoy + Event::QueueFilled(1) => schedule_release, ], }, - state blocked { - transitions: [ - Event::QueueEmpty(0) => send_decoy, - Event::SendBlocked => wait, - ] - }, - state wait { - transitions: [ - Event::QueueEmpty(0) => do_block, - ] - }, } - .expect("predefined machine should be valid") + .expect("preconstructed machine should be valid") }