snark/work_verify/
snark_work_verify_reducer.rs1use openmina_core::{bug_condition, snark::Snark, Substate, SubstateAccess};
2use redux::EnablingCondition;
3
4use crate::work_verify_effectful::SnarkWorkVerifyEffectfulAction;
5
6use super::{
7 SnarkWorkVerifyAction, SnarkWorkVerifyActionWithMetaRef, SnarkWorkVerifyState,
8 SnarkWorkVerifyStatus,
9};
10
11pub fn reducer<State, Action>(
12 mut state_context: Substate<Action, State, SnarkWorkVerifyState>,
13 action: SnarkWorkVerifyActionWithMetaRef<'_>,
14) where
15 State: SubstateAccess<SnarkWorkVerifyState> + SubstateAccess<crate::SnarkState>,
16 Action: From<SnarkWorkVerifyAction>
17 + From<SnarkWorkVerifyEffectfulAction>
18 + From<redux::AnyAction>
19 + EnablingCondition<State>,
20{
21 let Ok(state) = state_context.get_substate_mut() else {
22 return;
24 };
25 let (action, meta) = action.split();
26
27 match action {
28 SnarkWorkVerifyAction::Init {
29 batch,
30 sender,
31 req_id,
32 on_error,
33 on_success,
34 } => {
35 state.jobs.add(SnarkWorkVerifyStatus::Init {
36 time: meta.time(),
37 batch: batch.clone(),
38 sender: sender.clone(),
39 on_error: on_error.clone(),
40 on_success: on_success.clone(),
41 });
42
43 let verifier_index = state.verifier_index.clone();
45 let verifier_srs = state.verifier_srs.clone();
46 let dispatcher = state_context.into_dispatcher();
47 dispatcher.push(SnarkWorkVerifyEffectfulAction::Init {
48 req_id: *req_id,
49 batch: batch.clone(),
50 verifier_index,
51 verifier_srs,
52 });
53 dispatcher.push(SnarkWorkVerifyAction::Pending { req_id: *req_id });
54 }
55 SnarkWorkVerifyAction::Pending { req_id } => {
56 if let Some(req) = state.jobs.get_mut(*req_id) {
57 *req = match req {
58 SnarkWorkVerifyStatus::Init {
59 batch,
60 sender,
61 on_error,
62 on_success,
63 ..
64 } => SnarkWorkVerifyStatus::Pending {
65 time: meta.time(),
66 batch: std::mem::take(batch),
67 sender: std::mem::take(sender),
68 on_error: on_error.clone(),
69 on_success: on_success.clone(),
70 },
71 _ => return,
72 };
73 }
74 }
75 SnarkWorkVerifyAction::Error { req_id, error } => {
76 let Some(req) = state.jobs.get_mut(*req_id) else {
77 bug_condition!(
78 "Invalid state for `SnarkWorkVerifyAction::Error` job not found with id: {}",
79 req_id
80 );
81 return;
82 };
83 let SnarkWorkVerifyStatus::Pending {
84 batch,
85 sender,
86 on_error,
87 ..
88 } = req
89 else {
90 bug_condition!(
91 "Invalid state of `SnarkWorkVerifyStatus` for `SnarkWorkVerifyAction::Error`"
92 );
93 return;
94 };
95 let callback = on_error.clone();
96 let sender = std::mem::take(sender);
97 let batch = std::mem::take(batch);
98 let job_ids = batch.iter().map(Snark::job_id).collect();
99 *req = SnarkWorkVerifyStatus::Error {
100 time: meta.time(),
101 batch,
102 sender: sender.clone(),
103 error: error.clone(),
104 };
105 let dispatcher = state_context.into_dispatcher();
107 dispatcher.push_callback(callback, (*req_id, sender, job_ids));
108 dispatcher.push(SnarkWorkVerifyAction::Finish { req_id: *req_id });
109 }
110 SnarkWorkVerifyAction::Success { req_id } => {
111 let Some(req) = state.jobs.get_mut(*req_id) else {
112 bug_condition!(
113 "Invalid state for `SnarkWorkVerifyAction::Success` job not found with id: {}",
114 req_id
115 );
116 return;
117 };
118 let SnarkWorkVerifyStatus::Pending {
119 batch,
120 sender,
121 on_success,
122 ..
123 } = req
124 else {
125 bug_condition!(
126 "Invalid state of `SnarkWorkVerifyStatus` for `SnarkWorkVerifyAction::Error`"
127 );
128 return;
129 };
130
131 let callback = on_success.clone();
132 let sender = std::mem::take(sender);
133 let batch = std::mem::take(batch);
134
135 *req = SnarkWorkVerifyStatus::Success {
136 time: meta.time(),
137 batch: batch.clone(),
138 sender: sender.clone(),
139 };
140
141 let dispatcher = state_context.into_dispatcher();
143 dispatcher.push_callback(callback, (*req_id, sender, batch));
144 dispatcher.push(SnarkWorkVerifyAction::Finish { req_id: *req_id });
145 }
146 SnarkWorkVerifyAction::Finish { req_id } => {
147 state.jobs.remove(*req_id);
148 }
149 }
150}