essential_vm/
state_read.rs1use crate::{
4 error::{MemoryError, OpAsyncError, OpAsyncResult, StackError},
5 Vm,
6};
7use core::{
8 future::Future,
9 pin::Pin,
10 task::{Context, Poll},
11};
12use essential_types::{convert::u8_32_from_word_4, ContentAddress, Key, Word};
13
14pub trait StateRead {
16 type Error: core::fmt::Debug + core::fmt::Display;
18 type Future: Future<Output = Result<Vec<Vec<Word>>, Self::Error>> + Unpin;
32
33 fn key_range(&self, contract_addr: ContentAddress, key: Key, num_values: usize)
36 -> Self::Future;
37}
38
39pub(crate) struct StateReadFuture<'vm, S>
43where
44 S: StateRead,
45{
46 future: S::Future,
48 mem_addr: usize,
50 pub(crate) vm: &'vm mut Vm,
52}
53
54impl<S> Future for StateReadFuture<'_, S>
55where
56 S: StateRead,
57{
58 type Output = OpAsyncResult<(), S::Error>;
61 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
62 match Pin::new(&mut self.future).poll(cx) {
63 Poll::Pending => Poll::Pending,
64 Poll::Ready(res) => {
65 let mem_addr = self.mem_addr;
66 let res = res
67 .map_err(OpAsyncError::StateRead)
68 .and_then(|words| write_values_to_memory(mem_addr, words, self.vm));
69 Poll::Ready(res)
70 }
71 }
72 }
73}
74
75pub fn key_range<'vm, S>(
77 state_read: &S,
78 contract_addr: &ContentAddress,
79 vm: &'vm mut Vm,
80) -> OpAsyncResult<StateReadFuture<'vm, S>, S::Error>
81where
82 S: StateRead,
83{
84 let mem_addr = vm.stack.pop()?;
85 let mem_addr = usize::try_from(mem_addr).map_err(|_| MemoryError::IndexOutOfBounds)?;
86 let future = read_key_range(state_read, contract_addr, vm)?;
87 Ok(StateReadFuture {
88 future,
89 mem_addr,
90 vm,
91 })
92}
93
94pub fn key_range_ext<'vm, S>(
96 state_read: &S,
97 vm: &'vm mut Vm,
98) -> OpAsyncResult<StateReadFuture<'vm, S>, S::Error>
99where
100 S: StateRead,
101{
102 let mem_addr = vm.stack.pop()?;
103 let mem_addr = usize::try_from(mem_addr).map_err(|_| MemoryError::IndexOutOfBounds)?;
104 let future = read_key_range_ext(state_read, vm)?;
105 Ok(StateReadFuture {
106 future,
107 mem_addr,
108 vm,
109 })
110}
111
112fn read_key_range<S>(
114 state_read: &S,
115 contract_addr: &ContentAddress,
116 vm: &mut Vm,
117) -> OpAsyncResult<S::Future, S::Error>
118where
119 S: StateRead,
120{
121 let num_keys = vm.stack.pop()?;
122 let num_keys = usize::try_from(num_keys).map_err(|_| StackError::IndexOutOfBounds)?;
123 let key = vm
124 .stack
125 .pop_len_words::<_, _, StackError>(|words| Ok(words.to_vec()))?;
126 Ok(state_read.key_range(contract_addr.clone(), key, num_keys))
127}
128
129fn read_key_range_ext<S>(state_read: &S, vm: &mut Vm) -> OpAsyncResult<S::Future, S::Error>
132where
133 S: StateRead,
134{
135 let num_keys = vm.stack.pop()?;
136 let num_keys = usize::try_from(num_keys).map_err(|_| StackError::IndexOutOfBounds)?;
137 let key = vm
138 .stack
139 .pop_len_words::<_, _, StackError>(|words| Ok(words.to_vec()))?;
140 let contract_addr = ContentAddress(u8_32_from_word_4(vm.stack.pop4()?));
141 Ok(state_read.key_range(contract_addr, key, num_keys))
142}
143
144fn write_values_to_memory<E>(
146 mem_addr: usize,
147 values: Vec<Vec<Word>>,
148 vm: &mut Vm,
149) -> OpAsyncResult<(), E> {
150 let values_len = Word::try_from(values.len()).map_err(|_| MemoryError::Overflow)?;
151 let index_len_pairs_len = values_len.checked_mul(2).ok_or(MemoryError::Overflow)?;
152 let mut mem_addr = Word::try_from(mem_addr).map_err(|_| MemoryError::IndexOutOfBounds)?;
153 let mut value_addr = mem_addr
154 .checked_add(index_len_pairs_len)
155 .ok_or(MemoryError::Overflow)?;
156 for value in values {
157 let value_len = Word::try_from(value.len()).map_err(|_| MemoryError::Overflow)?;
158 vm.memory.store_range(mem_addr, &[value_addr, value_len])?;
160 vm.memory.store_range(value_addr, &value)?;
162 value_addr += value_len;
164 mem_addr += 2;
165 }
166 Ok(())
167}