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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::str;
extern "C" {
fn print_str(ptr: *const u8, len: usize);
fn upgrade_code(code_ptr: *const u8, code_len: usize);
fn execute_code(execute_msg_ptr: *const u8, execute_msg_len: usize);
fn get_length(length_result_ptr: *const usize, key_ptr: *const u8, key_len: usize);
fn get_state(key_ptr: *const u8, key_len: usize, result_vec_ptr: *const u8);
fn set_state(key_ptr: *const u8, key_len: usize, value_ptr: *const u8, value_len: usize);
}
pub fn print(msg: &str) {
unsafe {
print_str(msg.as_ptr(), msg.len());
}
}
fn get_length_from_host(key: &[u8]) -> usize {
let value_length: usize = 0;
unsafe {
let len_ptr: *const usize = &value_length;
get_length(len_ptr, key.as_ptr(), key.len() as usize);
}
value_length
}
pub fn read<K: AsRef<[u8]>>(key: K) -> Option<Vec<u8>> {
let value_length = get_length_from_host(key.as_ref());
if value_length == 0 {
return None;
}
let value_bytes = vec![0; value_length];
unsafe {
get_state(
key.as_ref().as_ptr(),
key.as_ref().len() as usize,
value_bytes.as_ptr(),
);
}
Some(value_bytes)
}
pub fn write<K: AsRef<[u8]>>(key: K, value: Vec<u8>) {
unsafe {
set_state(
key.as_ref().as_ptr(),
key.as_ref().len(),
value.as_ptr(),
value.len() as usize,
)
};
}
pub fn upgrade(code: Vec<u8>) {
unsafe { upgrade_code(code.as_ptr(), code.len() as usize) };
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ExecutionMessage {
pub code_key: Vec<u8>,
pub store_key: Vec<u8>,
pub entry_function_name: String,
}
pub fn execute(code_key: Vec<u8>, store_key: Vec<u8>, entry_function_name: &str) {
let execute_msg = ExecutionMessage {
code_key,
store_key,
entry_function_name: String::from(entry_function_name),
};
let execute_msg_bytes: Vec<u8> = bincode::serialize(&execute_msg).unwrap();
unsafe {
execute_code(execute_msg_bytes.as_ptr(), execute_msg_bytes.len() as usize);
}
}
pub struct Child {
code_key: Vec<u8>,
store_key: Vec<u8>,
}
impl Child {
pub fn new(code_key: Vec<u8>, store_key: Vec<u8>) -> Child {
Child {
code_key,
store_key,
}
}
pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Option<Vec<u8>> {
let current_store = read(&self.store_key);
match current_store {
Some(store_bytes) => {
let store: HashMap<Vec<u8>, Vec<u8>> = bincode::deserialize(&store_bytes).unwrap();
let value = store.get(&key.as_ref().to_vec());
match value {
Some(val) => Some(val.to_vec()),
None => None,
}
}
None => None,
}
}
pub fn set<K: AsRef<[u8]>, V: AsRef<[u8]>>(&self, key: K, value: V) {
let current_store = read(&self.store_key);
let mut child_store = match current_store {
Some(store_bytes) => {
let deserialized_store: HashMap<Vec<u8>, Vec<u8>> =
bincode::deserialize(&store_bytes[..]).unwrap();
deserialized_store
}
None => {
let child_store: HashMap<Vec<u8>, Vec<u8>> = HashMap::new();
child_store
}
};
child_store.insert(key.as_ref().to_vec(), value.as_ref().to_vec());
let serialized_store = bincode::serialize(&child_store).unwrap();
write(&self.store_key, serialized_store);
}
pub fn call(&self, func_name: &str) {
execute(self.code_key.clone(), self.store_key.clone(), func_name);
}
}