miden_core/deferred/
mod.rs1mod node;
12mod precompile;
13mod precompile_registry;
14mod state;
15mod wire;
16
17use alloc::boxed::Box;
18
19pub use node::{DataChunk, Digest, Node, NodeType, Payload, TRUE_DIGEST, Tag};
20pub use precompile::{Precompile, precompile_id};
21pub use precompile_registry::PrecompileRegistry;
22pub use state::{DeferredContext, DeferredState};
23pub use wire::{DeferredStateWire, IntegrityError, TRUE_INDEX, WireEntry};
24
25use crate::Word;
26
27pub type DeferredRoot = Digest;
29
30pub const DEFERRED_ROOT_DOMAIN: Word = Word::new(Tag::AND.as_word());
32
33pub const DEFAULT_MAX_DEFERRED_ELEMENTS: usize = 1 << 20;
35
36pub fn fold_deferred_root(root: DeferredRoot, statement: Digest) -> DeferredRoot {
38 Node::and(root, statement).digest()
39}
40
41#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
43pub struct DeferredRootTracker {
44 root: DeferredRoot,
45}
46
47impl DeferredRootTracker {
48 pub fn new() -> Self {
49 Self::default()
50 }
51
52 pub fn from_root(root: DeferredRoot) -> Self {
53 Self { root }
54 }
55
56 pub fn root(&self) -> DeferredRoot {
57 self.root
58 }
59
60 pub fn record_statement(&mut self, statement: Digest) {
61 self.root = fold_deferred_root(self.root, statement);
62 }
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
70pub enum DeferredError {
71 #[error("invalid or unknown deferred tag")]
72 InvalidTag,
73 #[error("referenced digest is not present in deferred state")]
74 MissingNode,
75 #[error("conflicting node definition for digest")]
76 ConflictingNode,
77 #[error("payload is not valid for the given tag")]
78 InvalidPayload,
79 #[error("equality assertion failed")]
80 AssertionFailed,
81 #[error("deferred insertion requires {num_elements} elements but only {max} remain")]
82 DeferredStateTooLarge { num_elements: usize, max: usize },
83 #[error("operation is not supported by this handler")]
84 Unsupported,
85 #[error("invalid deferred root transition: expected {expected:?}, got {actual:?}")]
86 InvalidDeferredRootTransition { expected: Digest, actual: Digest },
87}
88
89#[derive(Debug, Clone, thiserror::Error)]
91pub enum PrecompileError {
92 #[error("deferred DAG is missing a node referenced during evaluation")]
94 MissingNode,
95
96 #[error("node failed precompile validation")]
98 InvalidNode,
99
100 #[error("deferred assertion failed: values disagree")]
102 AssertionFailed,
103
104 #[error(transparent)]
106 Other(#[from] DeferredError),
107
108 #[error("precompile `{name}`: {source}")]
112 Precompile {
113 name: &'static str,
114 source: Box<PrecompileError>,
115 },
116}
117
118impl PrecompileError {
119 pub fn root(&self) -> &PrecompileError {
121 match self {
122 PrecompileError::Precompile { source, .. } => source.root(),
123 other => other,
124 }
125 }
126
127 pub(crate) fn with_precompile(name: &'static str, source: PrecompileError) -> Self {
128 Self::Precompile { name, source: Box::new(source) }
129 }
130}