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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#![cfg_attr(not(feature = "std"), no_std)]
use self::ext::Ext;
use ceres_executor::{derive::SealCall, Error, Memory, Result};
use ceres_std::{vec, Rc, Vec};
use ceres_support::{
convert,
traits::{self, Frame},
types::Metadata,
};
use core::cell::RefCell;
use parity_scale_codec::Encode;
use parity_wasm::elements::Module;
pub type StorageKey = [u8; 32];
mod chain;
mod contract;
mod ext;
mod instantiate;
mod memory;
mod restore;
mod ri;
mod schedule;
mod storage;
mod termination;
mod transfer;
mod tx;
mod util;
pub use self::{ri::RuntimeInterfaces, tx::Transaction};
pub struct Sandbox {
pub input: Option<Vec<u8>>,
pub ret: Option<Vec<u8>>,
pub ext: Ext,
pub tx: tx::Transaction,
pub cache: Rc<RefCell<dyn Frame<Memory>>>,
pub events: Vec<(Vec<[u8; 32]>, Vec<u8>)>,
pub ri: Vec<SealCall<Self>>,
}
impl Sandbox {
pub fn new(
cache: Rc<RefCell<impl Frame<Memory> + 'static>>,
ri: Vec<SealCall<Self>>,
) -> Sandbox {
Sandbox {
input: None,
ret: None,
ext: Default::default(),
events: vec![],
tx: Default::default(),
cache,
ri,
}
}
pub fn prepare(&mut self, code_hash: [u8; 32]) -> Result<()> {
let mut cache_mut = self.cache.borrow_mut();
if cache_mut.switch(code_hash).is_none() {
let contract = cache_mut.get(&code_hash).ok_or(Error::CodeNotFound)?;
let limit = ceres_executor::scan_imports(&Module::from_bytes(&contract)?)?;
let memory = Memory::new(limit.0, limit.1)?;
cache_mut.push(code_hash, memory);
}
drop(cache_mut);
Ok(())
}
pub fn load_metadata(&mut self, meta: &Metadata) -> Result<[u8; 32]> {
let code_hash =
convert::parse_code_hash(&meta.source.hash).ok_or(Error::DecodeContractFailed)?;
self.cache.borrow_mut().set(
code_hash.to_vec(),
Metadata::wasm(&meta.encode()).ok_or(Error::DecodeContractFailed)?,
);
Ok(code_hash)
}
}
impl traits::Ext<Memory, Vec<SealCall<Self>>> for Sandbox {
fn code(&self, hash: [u8; 32]) -> Option<Vec<u8>> {
self.cache.borrow().get(&hash).map(|v| v.to_vec())
}
fn memory(&self) -> Option<Memory> {
self.cache.borrow().memory()
}
fn seal_call(&self) -> Vec<SealCall<Self>> {
self.ri.clone()
}
}