1#![deny(missing_docs, unsafe_code)]
28
29pub use access::Access;
30pub use cached::LazyCache;
31#[doc(inline)]
32pub use essential_asm::{self as asm, Op};
33pub use essential_types as types;
34#[doc(inline)]
35pub use memory::Memory;
36#[doc(inline)]
37pub use op_access::OpAccess;
38#[doc(inline)]
39pub use repeat::Repeat;
40#[doc(inline)]
41pub use stack::Stack;
42#[doc(inline)]
43pub use state_read::StateRead;
44#[doc(inline)]
45pub use state_read::StateReads;
46#[doc(inline)]
47pub use total_control_flow::ProgramControlFlow;
48#[doc(inline)]
49pub use vm::Vm;
50
51mod access;
52mod alu;
53pub mod bytecode;
54mod cached;
55mod compute;
56mod crypto;
57pub mod error;
58mod memory;
59mod op_access;
60mod pred;
61mod repeat;
62mod sets;
63mod stack;
64mod state_read;
65pub mod sync;
66mod total_control_flow;
67mod vm;
68
69#[cfg(test)]
70pub(crate) mod utils {
71 use crate::{StateRead, StateReads};
72
73 pub struct EmptyState;
74 impl StateRead for EmptyState {
75 type Error = String;
76
77 fn key_range(
78 &self,
79 _contract_addr: essential_types::ContentAddress,
80 _key: essential_types::Key,
81 _num_values: usize,
82 ) -> Result<Vec<Vec<essential_asm::Word>>, Self::Error> {
83 Ok(vec![])
84 }
85 }
86
87 impl StateReads for EmptyState {
88 type Error = String;
89 type Pre = Self;
90 type Post = Self;
91
92 fn pre(&self) -> &Self::Pre {
93 self
94 }
95
96 fn post(&self) -> &Self::Post {
97 self
98 }
99 }
100}
101
102pub type BytecodeMapped<Bytes = Vec<u8>> = bytecode::BytecodeMapped<Op, Bytes>;
104pub type BytecodeMappedSlice<'a> = bytecode::BytecodeMappedSlice<'a, Op>;
106
107pub type Gas = u64;
109
110#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
112pub struct GasLimit {
113 pub per_yield: Gas,
115 pub total: Gas,
117}
118
119pub trait OpGasCost: Send + Sync {
121 fn op_gas_cost(&self, op: &Op) -> Gas;
123}
124
125impl GasLimit {
126 pub const DEFAULT_PER_YIELD: Gas = 4_096;
130
131 pub const UNLIMITED: Self = Self {
133 per_yield: Self::DEFAULT_PER_YIELD,
134 total: Gas::MAX,
135 };
136}
137
138impl<F> OpGasCost for F
139where
140 F: Fn(&Op) -> Gas + Send + Sync,
141{
142 fn op_gas_cost(&self, op: &Op) -> Gas {
143 (*self)(op)
144 }
145}
146
147#[cfg(feature = "tracing")]
153pub(crate) fn trace_op_res<OA, T, E>(
154 oa: &OA,
155 pc: usize,
156 stack: &Stack,
157 memory: &Memory,
158 parent_memory: &Vec<std::sync::Arc<Memory>>,
159 halt: bool,
160 op_res: &Result<T, E>,
161) where
162 OA: OpAccess,
163 OA::Op: core::fmt::Debug,
164 E: core::fmt::Display,
165{
166 let op = oa
167 .op_access(pc)
168 .expect("must exist as retrieved previously")
169 .expect("must exist as retrieved previously");
170 let pc_op = format!("0x{:02X}: {op:?}", pc);
171 match op_res {
172 Ok(_) => {
173 if parent_memory.is_empty() {
174 tracing::trace!("{pc_op}\n ├── {:?}\n └── {:?}", stack, memory)
175 } else {
176 tracing::trace!(
177 "{pc_op}\n ├── {:?}\n ├── {:?}\n ├── {:?}\n └── {:?}",
178 stack,
179 memory,
180 parent_memory,
181 halt
182 )
183 }
184 }
185 Err(ref err) => {
186 tracing::trace!("{pc_op}");
187 tracing::debug!("{err}");
188 }
189 }
190}