1use crate::store::unix_now;
8use crate::{DdError, DropEnvelope, ErrorCode, Result};
9
10pub const SEAL_UNTIL_EXT: &str = "dd.seal-until";
11pub const SEAL_QUORUM_EXT: &str = "dd.seal-quorum";
12
13pub fn seal_until(env: &DropEnvelope) -> Option<u64> {
14 env.extensions
15 .iter()
16 .find(|e| e.name == SEAL_UNTIL_EXT)
17 .and_then(|e| {
18 if e.data.len() == 8 {
19 Some(u64::from_be_bytes(e.data.clone().try_into().ok()?))
20 } else {
21 None
22 }
23 })
24}
25
26pub fn seal_quorum(env: &DropEnvelope) -> Option<u32> {
27 env.extensions
28 .iter()
29 .find(|e| e.name == SEAL_QUORUM_EXT)
30 .and_then(|e| {
31 if e.data.len() == 4 {
32 Some(u32::from_be_bytes(e.data.clone().try_into().ok()?))
33 } else {
34 None
35 }
36 })
37}
38
39pub fn enforce(env: &DropEnvelope, now: u64, receipt_issuers: u32) -> Result<()> {
40 if let Some(until) = seal_until(env)
41 && now < until
42 {
43 return Err(DdError::protocol(
44 ErrorCode::Ddp1009Sealed,
45 format!("sealed until {until} (policy; not a crypto time-lock)"),
46 ));
47 }
48 if let Some(need) = seal_quorum(env)
49 && receipt_issuers < need
50 {
51 return Err(DdError::protocol(
52 ErrorCode::Ddp1009Sealed,
53 format!("sealed until {need} receipts (have {receipt_issuers})"),
54 ));
55 }
56 let _ = unix_now;
57 Ok(())
58}