Skip to main content

acta_maker_sdk/ws/vault/
tx.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2
3use crate::chain::vault::VaultIntentError;
4
5#[derive(Debug, thiserror::Error)]
6#[non_exhaustive]
7pub enum VaultTxError {
8    #[error("{field} `{deadline}` is not a unix timestamp")]
9    InvalidDeadline {
10        field: &'static str,
11        deadline: String,
12    },
13    #[error("{field} has passed: deadline {deadline}, now {now}")]
14    Expired {
15        field: &'static str,
16        deadline: u64,
17        now: u64,
18    },
19    #[error("system clock is before the unix epoch")]
20    ClockBeforeEpoch,
21    #[error(transparent)]
22    Intent(#[from] VaultIntentError),
23}
24
25pub(super) fn ensure_deadline_ahead(
26    field: &'static str,
27    deadline: &str,
28) -> Result<u64, VaultTxError> {
29    ensure_deadline_ahead_at(field, deadline, unix_now()?)
30}
31
32pub(super) fn ensure_deadline_ahead_at(
33    field: &'static str,
34    deadline: &str,
35    now: u64,
36) -> Result<u64, VaultTxError> {
37    let deadline_secs =
38        deadline
39            .trim()
40            .parse::<u64>()
41            .map_err(|_| VaultTxError::InvalidDeadline {
42                field,
43                deadline: deadline.to_owned(),
44            })?;
45    ensure_ahead(field, deadline_secs, now)
46}
47
48pub(super) fn ensure_system_time_ahead(
49    field: &'static str,
50    deadline: SystemTime,
51) -> Result<u64, VaultTxError> {
52    let deadline_secs = deadline
53        .duration_since(UNIX_EPOCH)
54        .map_err(|_| VaultTxError::ClockBeforeEpoch)?
55        .as_secs();
56    ensure_ahead(field, deadline_secs, unix_now()?)
57}
58
59fn ensure_ahead(field: &'static str, deadline: u64, now: u64) -> Result<u64, VaultTxError> {
60    if now >= deadline {
61        return Err(VaultTxError::Expired {
62            field,
63            deadline,
64            now,
65        });
66    }
67    Ok(deadline)
68}
69
70fn unix_now() -> Result<u64, VaultTxError> {
71    SystemTime::now()
72        .duration_since(UNIX_EPOCH)
73        .map(|elapsed| elapsed.as_secs())
74        .map_err(|_| VaultTxError::ClockBeforeEpoch)
75}