essential_vm/
state_read.rs1use crate::{
4 error::{MemoryError, OpError, OpResult, StackError, StateReadArgError},
5 Memory, Stack,
6};
7use essential_types::{convert::u8_32_from_word_4, ContentAddress, Key, Value, Word};
8
9#[cfg(test)]
10mod tests;
11
12pub trait StateRead: Send + Sync {
14 type Error: core::fmt::Debug + core::fmt::Display;
16
17 fn key_range(
20 &self,
21 contract_addr: ContentAddress,
22 key: Key,
23 num_values: usize,
24 ) -> Result<Vec<Vec<Word>>, Self::Error>;
25}
26
27pub trait StateReads: Send + Sync {
29 type Error: core::fmt::Debug + core::fmt::Display + Send;
31
32 type Pre: StateRead<Error = Self::Error>;
34
35 type Post: StateRead<Error = Self::Error>;
37
38 fn pre(&self) -> &Self::Pre;
40
41 fn post(&self) -> &Self::Post;
43}
44
45impl<S, P> StateReads for (S, P)
46where
47 S: StateRead,
48 P: StateRead<Error = S::Error>,
49 S::Error: Send,
50{
51 type Error = S::Error;
52
53 type Pre = S;
54
55 type Post = P;
56
57 fn pre(&self) -> &Self::Pre {
58 &self.0
59 }
60
61 fn post(&self) -> &Self::Post {
62 &self.1
63 }
64}
65pub fn key_range<S>(
68 state_read: &S,
69 contract_addr: &ContentAddress,
70 stack: &mut Stack,
71 memory: &mut Memory,
72) -> OpResult<(), S::Error>
73where
74 S: StateRead,
75{
76 let mem_addr = pop_memory_address(stack)?;
77 let values = read_key_range(state_read, contract_addr, stack)?;
78 write_values_to_memory(mem_addr, values, memory)?;
79 Ok(())
80}
81
82pub fn key_range_ext<S>(
85 state_read: &S,
86 stack: &mut Stack,
87 memory: &mut Memory,
88) -> OpResult<(), S::Error>
89where
90 S: StateRead,
91{
92 let mem_addr = pop_memory_address(stack)?;
93 let values = read_key_range_ext(state_read, stack)?;
94 write_values_to_memory(mem_addr, values, memory)?;
95 Ok(())
96}
97
98fn read_key_range<S>(
101 state_read: &S,
102 contract_addr: &ContentAddress,
103 stack: &mut Stack,
104) -> OpResult<Vec<Value>, S::Error>
105where
106 S: StateRead,
107{
108 let (key, num_keys) = pop_key_range_args(stack)?;
109 state_read
110 .key_range(contract_addr.clone(), key, num_keys)
111 .map_err(OpError::StateRead)
112}
113
114fn read_key_range_ext<S>(state_read: &S, stack: &mut Stack) -> OpResult<Vec<Value>, S::Error>
118where
119 S: StateRead,
120{
121 let (key, num_keys) = pop_key_range_args(stack)?;
122 let contract_addr = ContentAddress(u8_32_from_word_4(stack.pop4()?));
123 state_read
124 .key_range(contract_addr, key, num_keys)
125 .map_err(OpError::StateRead)
126}
127
128fn pop_memory_address(stack: &mut Stack) -> Result<usize, StateReadArgError> {
130 let mem_addr = stack.pop()?;
131 let mem_addr = usize::try_from(mem_addr).map_err(|_| MemoryError::IndexOutOfBounds)?;
132 Ok(mem_addr)
133}
134
135fn pop_key_range_args(stack: &mut Stack) -> Result<(Key, usize), StackError> {
137 let num_keys = stack.pop()?;
138 let num_keys = usize::try_from(num_keys).map_err(|_| StackError::IndexOutOfBounds)?;
139 let key = stack.pop_len_words::<_, _, StackError>(|words| Ok(words.to_vec()))?;
140 Ok((key, num_keys))
141}
142
143fn write_values_to_memory(
145 mem_addr: usize,
146 values: Vec<Vec<Word>>,
147 memory: &mut Memory,
148) -> Result<(), MemoryError> {
149 let values_len = Word::try_from(values.len()).map_err(|_| MemoryError::Overflow)?;
150 let index_len_pairs_len = values_len.checked_mul(2).ok_or(MemoryError::Overflow)?;
151 let mut mem_addr = Word::try_from(mem_addr).map_err(|_| MemoryError::IndexOutOfBounds)?;
152 let mut value_addr = mem_addr
153 .checked_add(index_len_pairs_len)
154 .ok_or(MemoryError::Overflow)?;
155 for value in values {
156 let value_len = Word::try_from(value.len()).map_err(|_| MemoryError::Overflow)?;
157 memory.store_range(mem_addr, &[value_addr, value_len])?;
159 memory.store_range(value_addr, &value)?;
161 value_addr += value_len;
163 mem_addr += 2;
164 }
165 Ok(())
166}