Skip to content

Commit 7496058

Browse files
conorschhdevalence
andauthored
backport: dex: hotfix for 2025-01-18 chain halt (#4996)
## Describe your changes This PR backports #4993, which was made against the `release/v0.81.x` branch, to the `main` branch, so it's included in ongoing development. Co-authored-by: Henry de Valence <[email protected]>
1 parent 4f39372 commit 7496058

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

crates/core/component/dex/src/component/action_handler/position/close.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ use anyhow::Result;
22
use async_trait::async_trait;
33
use cnidarium::StateWrite;
44
use cnidarium_component::ActionHandler;
5-
use penumbra_proto::{DomainType as _, StateWriteProto as _};
65

7-
use crate::{component::PositionManager, event, lp::action::PositionClose};
6+
use crate::{component::PositionManager, lp::action::PositionClose};
87

98
#[async_trait]
109
/// Debits an opened position NFT and credits a closed position NFT.
@@ -22,15 +21,7 @@ impl ActionHandler for PositionClose {
2221
// lose the ability to do block-scoped JIT liquidity, where a single
2322
// transaction opens and closes a position, keeping liquidity live only
2423
// during that block's batch swap execution.
25-
state.queue_close_position(self.position_id);
26-
27-
// queue position close you will...
28-
state.record_proto(
29-
event::EventQueuePositionClose {
30-
position_id: self.position_id,
31-
}
32-
.to_proto(),
33-
);
24+
state.queue_close_position(self.position_id).await?;
3425

3526
Ok(())
3627
}

crates/core/component/dex/src/component/position_manager.rs

+31-4
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,37 @@ pub trait PositionManager: StateWrite + PositionRead {
211211
}
212212

213213
/// Queues a position to be closed at the end of the block, after batch execution.
214-
fn queue_close_position(&mut self, id: position::Id) {
215-
let mut to_close = self.pending_position_closures();
216-
to_close.push_back(id);
217-
self.object_put(state_key::pending_position_closures(), to_close);
214+
async fn queue_close_position(&mut self, id: position::Id) -> Result<()> {
215+
tracing::debug!(
216+
?id,
217+
"checking current position state before queueing for closure"
218+
);
219+
let current_state = self
220+
.position_by_id(&id)
221+
.await
222+
.expect("fetching position should not fail")
223+
.ok_or_else(|| anyhow::anyhow!("could not find position {} to close", id))?
224+
.tap(|lp| tracing::trace!(prev_state = ?lp, "retrieved previous lp state"));
225+
226+
if current_state.state == position::State::Opened {
227+
tracing::debug!(
228+
?current_state.state,
229+
"queueing opened position for closure"
230+
);
231+
let mut to_close = self.pending_position_closures();
232+
to_close.push_back(id);
233+
self.object_put(state_key::pending_position_closures(), to_close);
234+
235+
// queue position close you will...
236+
self.record_proto(event::EventQueuePositionClose { position_id: id }.to_proto());
237+
} else {
238+
tracing::debug!(
239+
?current_state.state,
240+
"skipping queueing for closure of non-opened position"
241+
);
242+
}
243+
244+
Ok(())
218245
}
219246

220247
/// Close all positions that have been queued for closure.

0 commit comments

Comments
 (0)