fvm_std/
runtime.rs

1use crate::prelude::*;
2use crate::types::LogLevel;
3
4pub(crate) mod env {
5    extern "C" {
6        pub(crate) fn fvm_storage_read(key_ptr: *const u8, key_len: u32, prefix_ptr: *const u8, prefix_len: u32,
7                                       val: *mut u8, vlen: u32, offset: u32) -> u32;
8        pub(crate) fn fvm_call_contract(addr: *const u8, input_ptr: *const u8, input_len: u32) -> u32;
9        pub(crate) fn fvm_cns_call_contract(cns: *const u8, cns_len: u32, input_ptr: *const u8, input_len: u32) -> u32;
10        pub(crate) fn fvm_storage_write(key_ptr: *const u8, key_len: u32, prefix_ptr: *const u8, prefix_len: u32, val: *const u8, vlen: u32);
11        pub(crate) fn fvm_storage_delete(key_ptr: *const u8, key_len: u32, prefix_ptr: *const u8, prefix_len: u32);
12        pub(crate) fn fvm_block_height() -> u64;
13        pub(crate) fn fvm_input_length() -> u32;
14        pub(crate) fn fvm_block_time() -> u64;
15        pub(crate) fn fvm_fetch_input(dst: *mut u8);
16        pub(crate) fn fvm_tx_hash(tx_hash: *const u8);
17        pub(crate) fn fvm_self_address(dest: *mut u8);
18        pub(crate) fn fvm_caller_address(dest: *mut u8);
19        pub(crate) fn fvm_origin_address(dest: *mut u8);
20        pub(crate) fn fvm_return(ptr: *const u8, len: u32);
21        pub(crate) fn fvm_revert(ptr: *const u8, len: u32) -> !;
22        pub(crate) fn fvm_log(ptr: *const u8, len: u32);
23        pub(crate) fn fvm_debug(class_prt: *const u8, class_len: u32, ptr: *const u8, len: u32, level: u32);
24        pub(crate) fn fvm_call_return(dst: *mut u8);
25        pub(crate) fn fvm_sha256(data_ptr: *const u8, len: u32, val: *mut u8);
26        pub(crate) fn fvm_add_list_key(list_name_ptr: *const u8, list_name_len: u32, index: u32) -> i64;
27        pub(crate) fn fvm_get_list_key(list_name_ptr: *const u8, list_name_len: u32, index: u32) -> i64;
28        pub(crate) fn fvm_remove_list_key(list_name_ptr: *const u8, list_name_len: u32, index: u32) -> i64;
29        pub(crate) fn fvm_write_list_keys(old_list_name_ptr: *const u8, old_list_name_len: u32, new_list_name_ptr: *const u8, new_list_name_len: u32, size: u32);
30    }
31}
32
33pub(crate) fn call_contract(addr: &Address, input: &[u8]) -> Vec<u8> {
34    let addr: &[u8] = addr.as_ref();
35    let size =
36        unsafe { env::fvm_call_contract(addr.as_ptr(), input.as_ptr(), input.len() as u32) };
37    let mut output = vec![0u8; size as usize];
38    if size != 0 {
39        let value = &mut output[..];
40        unsafe {
41            env::fvm_call_return(value.as_mut_ptr());
42        }
43    }
44
45    output
46}
47
48pub(crate) fn cns_call_contract(cns: &[u8], input: &[u8]) -> Vec<u8> {
49    let size =
50        unsafe { env::fvm_cns_call_contract(cns.as_ptr(), cns.len() as u32, input.as_ptr(), input.len() as u32) };
51    let mut output = vec![0u8; size as usize];
52    if size != 0 {
53        let value = &mut output[..];
54        unsafe {
55            env::fvm_call_return(value.as_mut_ptr());
56        }
57    }
58
59    output
60}
61
62
63pub(crate) fn storage_write(key: &[u8], prefix: &[u8], val: &[u8]) {
64    unsafe {
65        env::fvm_storage_write(key.as_ptr(), key.len() as u32,
66                               prefix.as_ptr(), prefix.len() as u32,
67                               val.as_ptr(), val.len() as u32);
68    }
69}
70
71pub(crate) fn storage_read(key: &[u8], prefix: &[u8]) -> Option<Vec<u8>> {
72    const INITIAL: usize = 32;
73    let mut val = vec![0; INITIAL];
74    let size = unsafe {
75        env::fvm_storage_read(
76            key.as_ptr(), key.len() as u32,
77            prefix.as_ptr(), prefix.len() as u32,
78            val.as_mut_ptr(),
79            val.len() as u32,
80            0,
81        )
82    };
83
84    // no value find for key
85    if size == 0 {
86        return None;
87    }
88    let size = size as usize;
89    val.resize(size, 0);
90    if size > INITIAL {
91        let value = &mut val[INITIAL..];
92        debug_assert!(value.len() == size - INITIAL);
93        unsafe {
94            env::fvm_storage_read(
95                key.as_ptr(), key.len() as u32,
96                prefix.as_ptr(), prefix.len() as u32,
97                value.as_mut_ptr(),
98                value.len() as u32,
99                INITIAL as u32,
100            )
101        };
102    }
103
104    Some(val)
105}
106
107pub(crate) fn storage_delete(key: &[u8], prefix: &[u8]) {
108    unsafe {
109        env::fvm_storage_delete(key.as_ptr(), key.len() as u32,
110                                prefix.as_ptr(), prefix.len() as u32);
111    }
112}
113
114pub(crate) fn block_time() -> u64 {
115    unsafe { env::fvm_block_time() }
116}
117
118pub(crate) fn block_height() -> u64 {
119    unsafe { env::fvm_block_height() }
120}
121
122pub(crate) fn self_address() -> Address {
123    let mut addr: Address = Address::zero();
124    unsafe {
125        env::fvm_self_address(addr.as_mut().as_mut_ptr());
126    }
127
128    addr
129}
130
131pub(crate) fn caller_address() -> Address {
132    let mut addr: Address = Address::zero();
133    unsafe {
134        env::fvm_caller_address(addr.as_mut().as_mut_ptr());
135    }
136    addr
137}
138
139pub(crate) fn origin_address() -> Address {
140    let mut addr: Address = Address::zero();
141    unsafe {
142        env::fvm_origin_address(addr.as_mut().as_mut_ptr());
143    }
144    addr
145}
146
147pub(crate) fn tx_hash() -> H256 {
148    let tx_hash = H256::zero();
149    unsafe {
150        env::fvm_tx_hash(tx_hash.as_ptr());
151    }
152    tx_hash
153}
154
155pub(crate) fn sha256(data: impl AsRef<[u8]>) -> H256 {
156    let data = data.as_ref();
157    let mut hash = H256::zero();
158    unsafe {
159        env::fvm_sha256(data.as_ptr(), data.len() as u32, hash.as_mut_ptr());
160    }
161    hash
162}
163
164
165pub(crate) fn input() -> Vec<u8> {
166    let len = unsafe { env::fvm_input_length() };
167
168    if len == 0 {
169        Vec::new()
170    } else {
171        let mut data = vec![0; len as usize];
172        unsafe {
173            env::fvm_fetch_input(data.as_mut_ptr());
174        }
175        data
176    }
177}
178
179pub(crate) fn ret(data: &[u8]) {
180    unsafe {
181        env::fvm_return(data.as_ptr(), data.len() as u32);
182    }
183}
184
185pub(crate) fn event(data: &[u8]) {
186    unsafe {
187        env::fvm_log(data.as_ptr(), data.len() as u32);
188    }
189}
190
191pub(crate) fn log(class_name: &[u8], data: &[u8], level: LogLevel) {
192    let level_type: u32 = match level {
193        LogLevel::CRITICAL => 0,
194        LogLevel::ERROR => 1,
195        LogLevel::WARNING => 2,
196        LogLevel::NOTICE => 3,
197        LogLevel::INFO => 4,
198        LogLevel::DEBUG => 5,
199    };
200    unsafe {
201        env::fvm_debug(class_name.as_ptr(), class_name.len() as u32, data.as_ptr(), data.len() as u32, level_type);
202    }
203}
204
205pub(crate) fn revert(msg: &str) -> ! {
206    unsafe {
207        env::fvm_revert(msg.as_ptr(), msg.len() as u32);
208    }
209}
210
211pub(crate) fn add_list_key(list_name: &[u8], index: u32) -> Option<i64> {
212    let key =
213        unsafe { env::fvm_add_list_key(list_name.as_ptr(), list_name.len() as u32, index) };
214    if key < 0 {
215        None
216    } else {
217        Some(key)
218    }
219}
220
221pub(crate) fn get_list_key(list_name: &[u8], index: u32) -> Option<i64> {
222    let key =
223        unsafe { env::fvm_get_list_key(list_name.as_ptr(), list_name.len() as u32, index) };
224    if key < 0 {
225        None
226    } else {
227        Some(key)
228    }
229}
230
231pub(crate) fn remove_list_key(list_name: &[u8], index: u32) -> Option<i64> {
232    let key =
233        unsafe { env::fvm_remove_list_key(list_name.as_ptr(), list_name.len() as u32, index) };
234    if key < 0 {
235        None
236    } else {
237        Some(key)
238    }
239}
240
241pub(crate) fn write_list_keys_back(old_list_name: &[u8], list_name: &[u8], size: u32) {
242    unsafe { env::fvm_write_list_keys(old_list_name.as_ptr(), old_list_name.len() as u32, list_name.as_ptr(), list_name.len() as u32, size) };
243}