crew_rs/
tx.rs

1use std::{cell::RefCell, collections::HashSet};
2
3use endr::{SetItemID, SetItem};
4use litl::impl_debug_as_litl;
5use ridl::signing::{Signed, SignerID};
6use serde_derive::{Deserialize, Serialize};
7use ti64::MsSinceEpoch;
8
9use crate::CrewChange;
10
11#[derive(Clone, Serialize, Deserialize)]
12pub struct CrewChangeTx {
13    pub(crate) content: Signed<CrewChangeTxContent>,
14    pub(crate) by: SignerID,
15}
16impl_debug_as_litl!(CrewChangeTx);
17
18impl CrewChangeTx {
19    pub fn as_test_entry(&self) -> CrewChangeTxEntry {
20        CrewChangeTxEntry(SetItem::new(self.clone(), None).id(), &self)
21    }
22}
23
24#[derive(Clone, Serialize, Deserialize)]
25
26pub struct CrewChangeTxContent {
27    pub(crate) changes: Vec<CrewChange>,
28    pub(crate) made_at: MsSinceEpoch,
29}
30impl_debug_as_litl!(CrewChangeTxContent);
31
32pub struct CrewChangeTxEntry<'a>(pub SetItemID, pub &'a CrewChangeTx);
33
34impl<'a> CrewChangeTxEntry<'a> {
35    pub fn correctly_signed(&self) -> Result<(), String> {
36        CORRECTLY_SIGNED_CACHE.with(|cache| {
37            if cache.borrow().contains(&self.0) {
38                return Ok(());
39            }
40            let result = self
41                .1
42                .content
43                .ensure_signed_by(&self.1.by)
44                .map_err(|err| err.to_string());
45            if result.is_ok() {
46                cache.borrow_mut().insert(self.0.clone());
47            }
48            result
49        })
50    }
51}
52
53thread_local! {
54    static CORRECTLY_SIGNED_CACHE: RefCell<HashSet<SetItemID>> = RefCell::new(HashSet::new());
55}