penumbra_sdk_auction/component/action_handler/dutch/
end.rs1use anyhow::{ensure, Result};
2use async_trait::async_trait;
3use cnidarium::StateWrite;
4use cnidarium_component::ActionHandler;
5use penumbra_sdk_proto::StateWriteProto;
6use tracing::instrument;
7
8use crate::auction::dutch::ActionDutchAuctionEnd;
9use crate::component::AuctionStoreRead;
10use crate::component::DutchAuctionManager;
11use crate::event;
12
13use anyhow::{bail, Context};
14
15#[async_trait]
16impl ActionHandler for ActionDutchAuctionEnd {
17 type CheckStatelessContext = ();
18 async fn check_stateless(&self, _context: ()) -> Result<()> {
19 Ok(())
20 }
21
22 #[instrument(name = "dutch_auction_end", skip(self, state))]
23 async fn check_and_execute<S: StateWrite>(&self, mut state: S) -> Result<()> {
24 let auction_id = self.auction_id;
25
26 let auction_state = state
27 .get_dutch_auction_by_id(auction_id)
28 .await
29 .context("the auction associated with this id is not a dutch auction")?;
30
31 let Some(auction) = auction_state else {
32 bail!("no auction found for id {auction_id}")
33 };
34
35 ensure!(
37 matches!(auction.state.sequence, 0 | 1),
38 "auction MUST have a sequence number set to opened (0) or closed (1) (got: {})",
39 auction.state.sequence
40 );
41
42 let auction_state = auction.state.clone();
44
45 state.end_auction(auction).await?;
47 state.record_proto(event::dutch_auction_closed_by_user(
49 auction_id,
50 auction_state,
51 ));
52
53 Ok(())
54 }
55}