nomos_runtime/
lib.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::str;
4
5extern "C" {
6    fn print_str(ptr: *const u8, len: usize);
7
8    // Allows this root state machine to upgrade in-place to a new WASM binary.
9    // Calling `upgrade` will destroy all child instances.
10    fn upgrade_code(code_ptr: *const u8, code_len: usize);
11    fn execute_code(execute_msg_ptr: *const u8, execute_msg_len: usize);
12
13    // Creates a child WASM instance using the specified binary.
14    // Returns a remote reference to the WASM instance.
15    // fn evaluate(ptr: *const u8, len: usize);
16
17    // Persistent state interface
18    fn get_length(length_result_ptr: *const usize, key_ptr: *const u8, key_len: usize);
19    fn get_state(key_ptr: *const u8, key_len: usize, result_vec_ptr: *const u8);
20    fn set_state(key_ptr: *const u8, key_len: usize, value_ptr: *const u8, value_len: usize);
21}
22
23pub fn print(msg: &str) {
24    unsafe {
25        print_str(msg.as_ptr(), msg.len());
26    }
27}
28
29/**
30 * Fetches the length of the value at the specified key.
31 */
32fn get_length_from_host(key: &[u8]) -> usize {
33    let value_length: usize = 0;
34    unsafe {
35        let len_ptr: *const usize = &value_length;
36        get_length(len_ptr, key.as_ptr(), key.len() as usize);
37    }
38    value_length
39}
40
41pub fn read<K: AsRef<[u8]>>(key: K) -> Option<Vec<u8>> {
42    let value_length = get_length_from_host(key.as_ref());
43    if value_length == 0 {
44        return None;
45    }
46    let value_bytes = vec![0; value_length];
47
48    // Tell the host to load up the value bytes for this key.
49    unsafe {
50        get_state(
51            key.as_ref().as_ptr(),
52            key.as_ref().len() as usize,
53            value_bytes.as_ptr(),
54        );
55    }
56
57    Some(value_bytes)
58}
59
60pub fn write<K: AsRef<[u8]>>(key: K, value: Vec<u8>) {
61    unsafe {
62        set_state(
63            key.as_ref().as_ptr(),
64            key.as_ref().len(),
65            value.as_ptr(),
66            value.len() as usize,
67        )
68    };
69}
70
71pub fn upgrade(code: Vec<u8>) {
72    unsafe { upgrade_code(code.as_ptr(), code.len() as usize) };
73}
74
75#[derive(Serialize, Deserialize, Debug)]
76pub struct ExecutionMessage {
77    pub code_key: Vec<u8>,
78    pub store_key: Vec<u8>,
79    pub entry_function_name: String,
80}
81
82pub fn execute(code_key: Vec<u8>, store_key: Vec<u8>, entry_function_name: &str) {
83    let execute_msg = ExecutionMessage {
84        code_key,
85        store_key,
86        entry_function_name: String::from(entry_function_name),
87    };
88    let execute_msg_bytes: Vec<u8> = bincode::serialize(&execute_msg).unwrap();
89    unsafe {
90        execute_code(execute_msg_bytes.as_ptr(), execute_msg_bytes.len() as usize);
91    }
92}
93
94pub struct Child {
95    code_key: Vec<u8>,
96    store_key: Vec<u8>,
97}
98
99impl Child {
100    pub fn new(code_key: Vec<u8>, store_key: Vec<u8>) -> Child {
101        Child {
102            code_key,
103            store_key,
104        }
105    }
106
107    pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Option<Vec<u8>> {
108        let current_store = read(&self.store_key);
109        match current_store {
110            Some(store_bytes) => {
111                let store: HashMap<Vec<u8>, Vec<u8>> = bincode::deserialize(&store_bytes).unwrap();
112                let value = store.get(&key.as_ref().to_vec());
113                match value {
114                    Some(val) => Some(val.to_vec()),
115                    None => None,
116                }
117            }
118            None => None,
119        }
120    }
121    pub fn set<K: AsRef<[u8]>, V: AsRef<[u8]>>(&self, key: K, value: V) {
122        let current_store = read(&self.store_key);
123        let mut child_store = match current_store {
124            Some(store_bytes) => {
125                let deserialized_store: HashMap<Vec<u8>, Vec<u8>> =
126                    bincode::deserialize(&store_bytes[..]).unwrap();
127                deserialized_store
128            }
129            None => {
130                let child_store: HashMap<Vec<u8>, Vec<u8>> = HashMap::new();
131                child_store
132            }
133        };
134
135        child_store.insert(key.as_ref().to_vec(), value.as_ref().to_vec());
136        let serialized_store = bincode::serialize(&child_store).unwrap();
137        write(&self.store_key, serialized_store);
138    }
139    pub fn call(&self, func_name: &str) {
140        execute(self.code_key.clone(), self.store_key.clone(), func_name);
141    }
142}