1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use crate::Sandbox;
use ceres_executor::{Error, Result};
use ceres_std::{vec, Vec};
use ceres_support::traits::Ext;
use parity_scale_codec::{Decode, DecodeAll, Encode};
impl Sandbox {
pub fn read_sandbox_memory(&self, ptr: u32, len: u32) -> Result<Vec<u8>> {
let mut buf = vec![0u8; len as usize];
self.read_sandbox_memory_into_buf(ptr, &mut buf)?;
Ok(buf.to_vec())
}
pub fn read_sandbox_memory_into_buf(&self, ptr: u32, buf: &mut [u8]) -> Result<()> {
self.memory()
.ok_or(Error::CodeNotFound)?
.get(ptr, buf)
.map_err(|_| Error::OutOfBounds)?;
Ok(())
}
pub fn read_sandbox_memory_as<D: Decode>(&mut self, ptr: u32, len: u32) -> Result<D> {
let buf = self.read_sandbox_memory(ptr, len)?;
let decoded = D::decode_all(&buf[..]).map_err(|_| Error::DecodeRuntimeValueFailed)?;
Ok(decoded)
}
pub fn write_sandbox_memory(&mut self, ptr: u32, buf: &[u8]) -> Result<()> {
self.memory()
.ok_or(Error::CodeNotFound)?
.set(ptr, buf)
.map_err(|_| Error::OutOfBounds)
}
pub fn write_sandbox_output(
&mut self,
out_ptr: u32,
out_len_ptr: u32,
buf: &[u8],
) -> Result<()> {
let buf_len = buf.len() as u32;
let len: u32 = self.read_sandbox_memory_as(out_len_ptr, 4)?;
if len < buf_len {
return Err(Error::OutputBufferTooSmall);
}
let memory = self.memory().ok_or(Error::CodeNotFound)?;
memory
.set(out_ptr, buf)
.and_then(|_| memory.set(out_len_ptr, &buf_len.encode()))
.map_err(|_| Error::OutOfBounds)?;
Ok(())
}
}