use std::cell::RefCell;
use std::rc::Rc;
use fvm_std::prelude::{Vec, H256, Address};
use fvm_std::types::LogLevel;
use crate::mock_runtime::{RuntimeInner, Runtime, setup_runtime};
pub struct MockRuntime {
inner: Rc<RefCell<RuntimeInner>>,
}
impl MockRuntime {
pub fn storage_write<K: AsRef<[u8]>, P: AsRef<[u8]>, V: AsRef<[u8]>>(&self, key: K, prefix: P, val: V) -> &Self {
let mut p = prefix.as_ref().to_vec();
let mut k = key.as_ref().to_vec();
p.append(&mut k);
self.inner.borrow_mut().storage.insert(p, val.as_ref().to_vec());
self
}
pub fn storage_read(&self, key: &[u8], prefix: &[u8]) -> Option<Vec<u8>> {
let mut p = prefix.as_ref().to_vec();
let mut k = key.as_ref().to_vec();
p.append(&mut k);
self.inner.borrow().storage.get(&p).map(|val| {
val.to_vec()
})
}
pub fn storage_delete(&self, key: &[u8], prefix: &[u8]) -> &Self {
let mut p = prefix.to_vec();
let mut s = key.to_vec();
p.append(&mut s);
self.inner.borrow_mut().storage.remove(&p);
self
}
pub fn block_time(&self, time: u64) -> &Self {
self.inner.borrow_mut().block_time = time;
self
}
pub fn block_height(&self, height: u64) -> &Self {
self.inner.borrow_mut().block_height = height;
self
}
pub fn self_address(&self, addr: &Address) -> &Self {
self.inner.borrow_mut().self_addr = addr.clone();
self
}
pub fn caller_address(&self, caller: &Address) -> &Self {
self.inner.borrow_mut().caller_addr = caller.clone();
self
}
pub fn origin_address(&self, origin: &Address) -> &Self {
self.inner.borrow_mut().origin_addr = origin.clone();
self
}
pub fn tx_hash(&self, tx_hash: &H256) -> &Self {
self.inner.borrow_mut().tx_hash = tx_hash.clone();
self
}
pub fn call_contracts<T: scale::Encode>(&self, call_rets: Vec<T>) -> &Self {
for c in call_rets {
self.inner.borrow_mut().call_return.insert(0, T::encode(&c))
}
self
}
pub fn call_contract<T: scale::Encode>(&self, call_ret: T) -> &Self {
self.inner.borrow_mut().call_return.insert(0, call_ret.encode());
self
}
pub fn input(&self, _dis: &[u8]) -> &Self {
self.inner.borrow_mut().input = _dis.to_vec();
self
}
pub fn ret(&self, msg: &[u8]) -> &Self {
self.inner.borrow_mut().ret = msg.to_vec();
self
}
pub fn get_log(&self, level: LogLevel) -> Vec<Vec<u8>> {
return self.inner.borrow().debug.get(&level.to_int()).expect("error level").to_vec();
}
pub fn get_event(&self) -> Vec<Vec<u8>> {
self.inner.borrow().log.to_vec()
}
pub fn get_ret(&self) -> Vec<u8> {
self.inner.borrow().ret.to_vec()
}
}
pub fn build_runtime() -> MockRuntime {
let inner = Rc::new(RefCell::new(RuntimeInner::default()));
let rt = Runtime { inner: inner.clone() };
setup_runtime(rt);
MockRuntime { inner }
}