simplicity/bit_machine/
limits.rs1use core::fmt;
10use std::error;
11
12const MAX_CELLS: usize = 2 * 1024 * 1024 * 1024 - 1;
22
23const MAX_FRAMES: usize = 1024 * 1024;
33
34#[non_exhaustive]
35#[derive(Clone, Debug)]
36pub enum LimitError {
37 MaxCellsExceeded {
38 got: usize,
40 max: usize,
42 bound: &'static str,
44 },
45 MaxFramesExceeded {
46 got: usize,
48 max: usize,
50 bound: &'static str,
52 },
53}
54
55impl fmt::Display for LimitError {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 let (limit, got, max, bound) = match self {
58 LimitError::MaxCellsExceeded { got, max, bound } => ("cells", got, max, bound),
59 LimitError::MaxFramesExceeded { got, max, bound } => ("frames", got, max, bound),
60 };
61 write!(
62 f,
63 "maximum number of {} exceeded (needed {}, maximum {}) (bound: {})",
64 limit, got, max, bound,
65 )
66 }
67}
68impl error::Error for LimitError {}
69
70impl LimitError {
71 fn check_max_cells(got: usize, bound: &'static str) -> Result<(), Self> {
72 if got > MAX_CELLS {
73 Err(Self::MaxCellsExceeded {
74 got,
75 max: MAX_CELLS,
76 bound,
77 })
78 } else {
79 Ok(())
80 }
81 }
82
83 fn check_max_frames(got: usize, bound: &'static str) -> Result<(), Self> {
84 if got > MAX_FRAMES {
85 Err(Self::MaxFramesExceeded {
86 got,
87 max: MAX_CELLS,
88 bound,
89 })
90 } else {
91 Ok(())
92 }
93 }
94
95 pub(super) fn check_program(program: &crate::RedeemNode) -> Result<(), Self> {
97 let source_ty_width = program.arrow().source.bit_width();
98 let target_ty_width = program.arrow().target.bit_width();
99 let bounds = program.bounds();
100
101 Self::check_max_cells(source_ty_width, "source type width")?;
102 Self::check_max_cells(target_ty_width, "target type width")?;
103 Self::check_max_cells(bounds.extra_cells, "extra cells")?;
104 Self::check_max_cells(
105 source_ty_width + target_ty_width,
106 "source + target type widths",
107 )?;
108 Self::check_max_cells(
109 source_ty_width + target_ty_width + bounds.extra_cells,
110 "source + target type widths + extra cells",
111 )?;
112
113 Self::check_max_frames(bounds.extra_frames, "extra frames")?;
114 Self::check_max_frames(
115 bounds.extra_frames + crate::analysis::IO_EXTRA_FRAMES,
116 "extra frames + fixed overhead",
117 )?;
118 Ok(())
119 }
120}