diff --git a/crates/core/component/dex/src/component/action_handler/position/close.rs b/crates/core/component/dex/src/component/action_handler/position/close.rs index f6ce7db1fa..9ba244126f 100644 --- a/crates/core/component/dex/src/component/action_handler/position/close.rs +++ b/crates/core/component/dex/src/component/action_handler/position/close.rs @@ -24,7 +24,8 @@ impl ActionHandler for PositionClose { // during that block's batch swap execution. state.queue_close_position(self.position_id); - state.record_proto(event::position_close(self)); + // queue position close you will... + state.record_proto(event::queue_position_close(self)); Ok(()) } diff --git a/crates/core/component/dex/src/component/position_manager.rs b/crates/core/component/dex/src/component/position_manager.rs index fed86752b1..cd3e3e4caa 100644 --- a/crates/core/component/dex/src/component/position_manager.rs +++ b/crates/core/component/dex/src/component/position_manager.rs @@ -279,8 +279,9 @@ pub trait PositionManager: StateWrite + PositionRead { mut new_state: Position, context: DirectedTradingPair, ) -> Result { + let position_id = new_state.id(); let prev_state = self - .position_by_id(&new_state.id()) + .position_by_id(&position_id) .await? .ok_or_else(|| anyhow::anyhow!("withdrew from unknown position {}", new_state.id()))?; @@ -311,21 +312,26 @@ pub trait PositionManager: StateWrite + PositionRead { prev_state.state ); + // We have already short-circuited no-op execution updates, so we can emit an execution + // event and not worry about duplicates. + self.record_proto(event::position_execution(&prev_state, &new_state, context)); + // Handle "close-on-fill": automatically flip the position state to "closed" if // either of the reserves are zero. if new_state.close_on_fill { if new_state.reserves.r1 == 0u64.into() || new_state.reserves.r2 == 0u64.into() { tracing::debug!( - id = ?new_state.id(), + ?position_id, r1 = ?new_state.reserves.r1, r2 = ?new_state.reserves.r2, "marking position as closed due to close-on-fill" ); + new_state.state = position::State::Closed; + self.record_proto(event::position_close_by_id(position_id)); } } - self.record_proto(event::position_execution(&prev_state, &new_state, context)); self.update_position(Some(prev_state), new_state).await } diff --git a/crates/core/component/dex/src/event.rs b/crates/core/component/dex/src/event.rs index 053f898c7a..64df9a8c62 100644 --- a/crates/core/component/dex/src/event.rs +++ b/crates/core/component/dex/src/event.rs @@ -40,6 +40,12 @@ pub fn position_open(position: &Position) -> pb::EventPositionOpen { } } +pub fn position_close_by_id(id: position::Id) -> pb::EventPositionClose { + pb::EventPositionClose { + position_id: Some(id.into()), + } +} + pub fn position_close(action: &PositionClose) -> pb::EventPositionClose { pb::EventPositionClose { position_id: Some(action.position_id.into()),