-
Notifications
You must be signed in to change notification settings - Fork 305
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
auction: first pass at schedule DA validation
- Loading branch information
Showing
1 changed file
with
55 additions
and
2 deletions.
There are no files selected for viewing
57 changes: 55 additions & 2 deletions
57
crates/core/component/auction/src/component/action_handler/dutch/schedule.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,71 @@ | ||
use anyhow::Result; | ||
use crate::component::auction::StateReadExt; | ||
use anyhow::{ensure, Result}; | ||
use async_trait::async_trait; | ||
use cnidarium::StateWrite; | ||
use cnidarium_component::ActionHandler; | ||
use penumbra_sct::component::clock::EpochRead; // AuctionRead? | ||
|
||
use crate::auction::dutch::actions::ActionDutchAuctionSchedule; | ||
|
||
#[async_trait] | ||
impl ActionHandler for ActionDutchAuctionSchedule { | ||
type CheckStatelessContext = (); | ||
async fn check_stateless(&self, _context: ()) -> Result<()> { | ||
let schedule = self; | ||
let end_height = schedule.description.end_height; | ||
let start_height = schedule.description.start_height; | ||
let step_count = schedule.description.step_count; | ||
|
||
// Check that the start and end height are valid. | ||
ensure!( | ||
start_height < end_height, | ||
"the start height MUST be strictly less than the end height (got: start={} >= end={})", | ||
start_height, | ||
end_height | ||
); | ||
|
||
// Check that the step count is positive. | ||
ensure!( | ||
step_count > 0, | ||
"step count MUST be greater than zero (got: {step_count})" | ||
); | ||
|
||
// Check that the step count is less than 1000. | ||
ensure!( | ||
step_count <= 1000, | ||
"the dutch auction step count MUST be less than 1000 (got: {step_count})", | ||
); | ||
|
||
// Check that height delta is a multiple of `step_count`. | ||
let block_window = end_height - start_height; | ||
ensure!( | ||
(block_window % step_count) == 0, | ||
"the block window ({block_window}) MUST be a multiple of the step count ({step_count})" | ||
); | ||
|
||
Ok(()) | ||
} | ||
|
||
async fn check_and_execute<S: StateWrite>(&self, mut _state: S) -> Result<()> { | ||
async fn check_and_execute<S: StateWrite>(&self, mut state: S) -> Result<()> { | ||
let schedule = self; | ||
|
||
// Check that `start_height` is in the future. | ||
let current_height = state.get_block_height().await?; | ||
let start_height = schedule.description.start_height; | ||
ensure!( | ||
start_height > current_height, | ||
"dutch auction MUST start in the future (start={}, current={})", | ||
start_height, | ||
current_height | ||
); | ||
|
||
// Check that the `auction_id` is unused. | ||
let id = schedule.description.id(); | ||
ensure!( | ||
!state.auction_id_exists(id).await, | ||
"the supplied auction id is already known to the chain (id={id})" | ||
); | ||
|
||
Ok(()) | ||
} | ||
} |