1use node_data::message::Message;
8use node_data::StepName;
9use tracing::{info, trace};
10
11use crate::commons::Database;
12use crate::execution_ctx::ExecutionCtx;
13use crate::operations::Operations;
14use crate::{proposal, ratification, validation};
15
16macro_rules! await_phase {
17 ($e:expr, $n:ident ( $($args:expr), *)) => {
18 {
19 match $e {
20 Phase::Proposal(p) => p.$n($($args,)*).await,
21 Phase::Validation(p) => p.$n($($args,)*).await,
22 Phase::Ratification(p) => p.$n($($args,)*).await,
23 }
24 }
25 };
26}
27
28pub enum Phase<T: Operations, D: Database> {
29 Proposal(proposal::step::ProposalStep<T, D>),
30 Validation(validation::step::ValidationStep<T, D>),
31 Ratification(ratification::step::RatificationStep),
32}
33
34impl<T: Operations + 'static, D: Database + 'static> Phase<T, D> {
35 pub fn to_step_name(&self) -> StepName {
36 match self {
37 Phase::Proposal(_) => StepName::Proposal,
38 Phase::Validation(_) => StepName::Validation,
39 Phase::Ratification(_) => StepName::Ratification,
40 }
41 }
42
43 pub async fn reinitialize(
44 &mut self,
45 msg: Message,
46 round: u64,
47 iteration: u8,
48 ) {
49 trace!(event = "init step", msg = format!("{:#?}", msg),);
50
51 await_phase!(self, reinitialize(msg, round, iteration))
52 }
53
54 pub async fn run(&mut self, mut ctx: ExecutionCtx<'_, T, D>) -> Message {
55 ctx.set_start_time();
56
57 let step = ctx.step_name();
58 let round = ctx.round_update.round;
59 let iter = ctx.iteration;
60 let timeout = ctx.iter_ctx.get_timeout(step);
61
62 info!(event = "Step started", ?step, round, iter, ?timeout);
64 let msg = await_phase!(self, run(ctx));
65 info!(event = "Step ended", ?step, round, iter);
66
67 msg
68 }
69}