fedimint_client_module/
db.rs
1use std::io::Cursor;
2
3use fedimint_core::core::OperationId;
4use fedimint_core::db::{DatabaseTransaction, DatabaseValue as _};
5use fedimint_core::encoding::Decodable;
6use fedimint_core::module::registry::ModuleDecoderRegistry;
7use fedimint_core::util::BoxFuture;
8
9pub type ClientModuleMigrationFn = for<'r, 'tx> fn(
12 &'r mut DatabaseTransaction<'tx>,
13 Vec<(Vec<u8>, OperationId)>, Vec<(Vec<u8>, OperationId)>, ) -> BoxFuture<
16 'r,
17 anyhow::Result<Option<(Vec<(Vec<u8>, OperationId)>, Vec<(Vec<u8>, OperationId)>)>>,
18>;
19
20type MigrateStateFn =
22 fn(OperationId, &mut Cursor<&[u8]>) -> anyhow::Result<Option<(Vec<u8>, OperationId)>>;
23
24pub fn migrate_state(
28 active_states: Vec<(Vec<u8>, OperationId)>,
29 inactive_states: Vec<(Vec<u8>, OperationId)>,
30 migrate: MigrateStateFn,
31) -> anyhow::Result<Option<(Vec<(Vec<u8>, OperationId)>, Vec<(Vec<u8>, OperationId)>)>> {
32 let mut new_active_states = Vec::with_capacity(active_states.len());
33 for (active_state, operation_id) in active_states {
34 let bytes = active_state.as_slice();
35
36 let decoders = ModuleDecoderRegistry::default();
37 let mut cursor = std::io::Cursor::new(bytes);
38 let module_instance_id = fedimint_core::core::ModuleInstanceId::consensus_decode_partial(
39 &mut cursor,
40 &decoders,
41 )?;
42
43 let state = match migrate(operation_id, &mut cursor)? {
44 Some((mut state, operation_id)) => {
45 let mut final_state = module_instance_id.to_bytes();
46 final_state.append(&mut state);
47 (final_state, operation_id)
48 }
49 None => (active_state, operation_id),
50 };
51
52 new_active_states.push(state);
53 }
54
55 let mut new_inactive_states = Vec::with_capacity(inactive_states.len());
56 for (inactive_state, operation_id) in inactive_states {
57 let bytes = inactive_state.as_slice();
58
59 let decoders = ModuleDecoderRegistry::default();
60 let mut cursor = std::io::Cursor::new(bytes);
61 let module_instance_id = fedimint_core::core::ModuleInstanceId::consensus_decode_partial(
62 &mut cursor,
63 &decoders,
64 )?;
65
66 let state = match migrate(operation_id, &mut cursor)? {
67 Some((mut state, operation_id)) => {
68 let mut final_state = module_instance_id.to_bytes();
69 final_state.append(&mut state);
70 (final_state, operation_id)
71 }
72 None => (inactive_state, operation_id),
73 };
74
75 new_inactive_states.push(state);
76 }
77
78 Ok(Some((new_active_states, new_inactive_states)))
79}