1use crate::Error;
4
5#[derive(Debug, Clone)]
8pub struct VerifyCtx {
9 depth: u32,
10 max_depth: u32,
11 budget: usize,
12}
13
14impl VerifyCtx {
15 pub const DEFAULT_MAX_DEPTH: u32 = 64;
16
17 pub fn new(buf_len: usize) -> Self {
19 Self::with_limits(Self::DEFAULT_MAX_DEPTH, buf_len.saturating_mul(8).max(1 << 20))
20 }
21
22 pub fn with_limits(max_depth: u32, budget: usize) -> Self {
23 VerifyCtx { depth: 0, max_depth, budget }
24 }
25
26 pub fn max_depth(&self) -> u32 {
27 self.max_depth
28 }
29
30 pub fn budget(&self) -> usize {
32 self.budget
33 }
34
35 #[inline]
36 pub fn enter(&mut self) -> Result<(), Error> {
37 if self.depth >= self.max_depth {
38 return Err(Error::DepthExceeded);
39 }
40 self.depth += 1;
41 Ok(())
42 }
43
44 #[inline]
45 pub fn leave(&mut self) {
46 self.depth = self.depth.saturating_sub(1);
47 }
48
49 #[inline]
50 pub fn charge(&mut self, bytes: usize) -> Result<(), Error> {
51 self.budget = self.budget.checked_sub(bytes).ok_or(Error::BudgetExceeded)?;
52 Ok(())
53 }
54}