fedimint_client_module/sm/
executor.rs1use std::io::{self, Read, Write};
2use std::sync::Arc;
3use std::time::SystemTime;
4
5use fedimint_core::core::{ModuleInstanceId, OperationId};
6use fedimint_core::db::DatabaseTransaction;
7use fedimint_core::encoding::{
8 Decodable, DecodeError, Encodable, decode_legacy_system_time_from_finite_reader,
9 encode_legacy_system_time, with_decoding_context,
10};
11use fedimint_core::module::registry::ModuleDecoderRegistry;
12use fedimint_core::{apply, async_trait_maybe_send, maybe_add_send_sync};
13
14use super::DynState;
15use crate::{AddStateMachinesResult, DynGlobalClientContext};
16
17pub type ContextGen =
18 Arc<maybe_add_send_sync!(dyn Fn(ModuleInstanceId, OperationId) -> DynGlobalClientContext)>;
19
20#[derive(Debug)]
22pub struct ActiveStateKey {
23 pub operation_id: OperationId,
25 pub state: DynState,
27}
28
29impl ActiveStateKey {
30 pub fn from_state(state: DynState) -> ActiveStateKey {
31 ActiveStateKey {
32 operation_id: state.operation_id(),
33 state,
34 }
35 }
36}
37
38impl Encodable for ActiveStateKey {
39 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
40 self.operation_id.consensus_encode(writer)?;
41 self.state.consensus_encode(writer)?;
42 Ok(())
43 }
44}
45
46impl Decodable for ActiveStateKey {
47 fn consensus_decode_partial<R: Read>(
48 reader: &mut R,
49 modules: &ModuleDecoderRegistry,
50 ) -> Result<Self, DecodeError> {
51 let operation_id = OperationId::consensus_decode_partial(reader, modules)?;
52 let state = DynState::consensus_decode_partial(reader, modules)?;
53
54 Ok(ActiveStateKey {
55 operation_id,
56 state,
57 })
58 }
59}
60
61#[derive(Debug, Copy, Clone)]
62pub struct ActiveStateMeta {
63 pub created_at: SystemTime,
64}
65
66impl Encodable for ActiveStateMeta {
67 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
68 encode_legacy_system_time(&self.created_at, writer)
69 }
70}
71
72impl Decodable for ActiveStateMeta {
73 fn consensus_decode_partial_from_finite_reader<R: Read>(
74 reader: &mut R,
75 modules: &ModuleDecoderRegistry,
76 ) -> Result<Self, DecodeError> {
77 Ok(Self {
78 created_at: with_decoding_context(
79 decode_legacy_system_time_from_finite_reader(reader, modules),
80 "Decoding named block field: ActiveStateMeta{ ... created_at ... }",
81 )?,
82 })
83 }
84}
85
86impl ActiveStateMeta {
87 pub fn into_inactive(self) -> InactiveStateMeta {
88 InactiveStateMeta {
89 created_at: self.created_at,
90 exited_at: fedimint_core::time::now(),
91 }
92 }
93}
94
95impl Default for ActiveStateMeta {
96 fn default() -> Self {
97 Self {
98 created_at: fedimint_core::time::now(),
99 }
100 }
101}
102
103#[derive(Debug, Clone)]
105pub struct InactiveStateKey {
106 pub operation_id: OperationId,
108 pub state: DynState,
109}
110
111impl InactiveStateKey {
112 pub fn from_state(state: DynState) -> InactiveStateKey {
113 InactiveStateKey {
114 operation_id: state.operation_id(),
115 state,
116 }
117 }
118}
119
120impl Encodable for InactiveStateKey {
121 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<(), std::io::Error> {
122 self.operation_id.consensus_encode(writer)?;
123 self.state.consensus_encode(writer)?;
124 Ok(())
125 }
126}
127
128impl Decodable for InactiveStateKey {
129 fn consensus_decode_partial<R: Read>(
130 reader: &mut R,
131 modules: &ModuleDecoderRegistry,
132 ) -> Result<Self, DecodeError> {
133 let operation_id = OperationId::consensus_decode_partial(reader, modules)?;
134 let state = DynState::consensus_decode_partial(reader, modules)?;
135
136 Ok(InactiveStateKey {
137 operation_id,
138 state,
139 })
140 }
141}
142
143#[derive(Debug, Copy, Clone)]
144pub struct InactiveStateMeta {
145 pub created_at: SystemTime,
146 pub exited_at: SystemTime,
147}
148
149impl Encodable for InactiveStateMeta {
150 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
151 encode_legacy_system_time(&self.created_at, writer)?;
152 encode_legacy_system_time(&self.exited_at, writer)
153 }
154}
155
156impl Decodable for InactiveStateMeta {
157 fn consensus_decode_partial_from_finite_reader<R: Read>(
158 reader: &mut R,
159 modules: &ModuleDecoderRegistry,
160 ) -> Result<Self, DecodeError> {
161 Ok(Self {
162 created_at: with_decoding_context(
163 decode_legacy_system_time_from_finite_reader(reader, modules),
164 "Decoding named block field: InactiveStateMeta{ ... created_at ... }",
165 )?,
166 exited_at: with_decoding_context(
167 decode_legacy_system_time_from_finite_reader(reader, modules),
168 "Decoding named block field: InactiveStateMeta{ ... exited_at ... }",
169 )?,
170 })
171 }
172}
173
174#[apply(async_trait_maybe_send!)]
175pub trait IExecutor {
176 async fn get_active_states(&self) -> Vec<(DynState, ActiveStateMeta)>;
177
178 async fn add_state_machines_dbtx(
179 &self,
180 dbtx: &mut DatabaseTransaction<'_>,
181 states: Vec<DynState>,
182 ) -> AddStateMachinesResult;
183}