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 crypto;
56pub mod error;
57mod memory;
58mod op_access;
59mod pred;
60mod repeat;
61mod sets;
62mod stack;
63mod state_read;
64pub mod sync;
65mod total_control_flow;
66mod vm;
67
68#[cfg(test)]
69pub(crate) mod utils {
70 use crate::{StateRead, StateReads};
71
72 pub struct EmptyState;
73 impl StateRead for EmptyState {
74 type Error = String;
75
76 fn key_range(
77 &self,
78 _contract_addr: essential_types::ContentAddress,
79 _key: essential_types::Key,
80 _num_values: usize,
81 ) -> Result<Vec<Vec<essential_asm::Word>>, Self::Error> {
82 Ok(vec![])
83 }
84 }
85
86 impl StateReads for EmptyState {
87 type Error = String;
88 type Pre = Self;
89 type Post = Self;
90
91 fn pre(&self) -> &Self::Pre {
92 self
93 }
94
95 fn post(&self) -> &Self::Post {
96 self
97 }
98 }
99}
100
101pub type BytecodeMapped<Bytes = Vec<u8>> = bytecode::BytecodeMapped<Op, Bytes>;
103pub type BytecodeMappedSlice<'a> = bytecode::BytecodeMappedSlice<'a, Op>;
105
106pub type Gas = u64;
108
109#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
111pub struct GasLimit {
112 pub per_yield: Gas,
114 pub total: Gas,
116}
117
118pub trait OpGasCost {
120 fn op_gas_cost(&self, op: &Op) -> Gas;
122}
123
124impl GasLimit {
125 pub const DEFAULT_PER_YIELD: Gas = 4_096;
129
130 pub const UNLIMITED: Self = Self {
132 per_yield: Self::DEFAULT_PER_YIELD,
133 total: Gas::MAX,
134 };
135}
136
137impl<F> OpGasCost for F
138where
139 F: Fn(&Op) -> Gas,
140{
141 fn op_gas_cost(&self, op: &Op) -> Gas {
142 (*self)(op)
143 }
144}
145
146#[cfg(feature = "tracing")]
152pub(crate) fn trace_op_res<OA, T, E>(
153 oa: &OA,
154 pc: usize,
155 stack: &Stack,
156 memory: &Memory,
157 op_res: &Result<T, E>,
158) where
159 OA: OpAccess,
160 OA::Op: core::fmt::Debug,
161 E: core::fmt::Display,
162{
163 let op = oa
164 .op_access(pc)
165 .expect("must exist as retrieved previously")
166 .expect("must exist as retrieved previously");
167 let pc_op = format!("0x{:02X}: {op:?}", pc);
168 match op_res {
169 Ok(_) => {
170 tracing::trace!("{pc_op}\n ├── {:?}\n └── {:?}", stack, memory)
171 }
172 Err(ref err) => {
173 tracing::trace!("{pc_op}");
174 tracing::debug!("{err}");
175 }
176 }
177}