1pub mod rust {
2
3 pub mod interpreter;
4}
5
6use std::collections::BTreeMap;
7use std::sync::{Arc, Mutex};
8
9use crate::rust::interpreter::compiler::compiler::Compiler;
10use f1r3fly_crypto::rust::hash::blake2b512_block::Blake2b512Block;
11use f1r3fly_crypto::rust::{hash::blake2b512_random::Blake2b512Random, public_key::PublicKey};
12use f1r3fly_models::rspace_plus_plus_types::*;
13use f1r3fly_models::{
14 rhoapi::{BindPattern, ListParWithRandom, Par, TaggedContinuation},
15 rholang_scala_rust_types::*,
16};
17use prost::Message;
18use f1r3fly_rspace_plus_plus::rspace::checkpoint::SoftCheckpoint;
19use f1r3fly_rspace_plus_plus::rspace::hashing::blake2b256_hash::Blake2b256Hash;
20use f1r3fly_rspace_plus_plus::rspace::hot_store::{new_dashmap, HotStoreState};
21use f1r3fly_rspace_plus_plus::rspace::internal::{Datum, WaitingContinuation};
22use f1r3fly_rspace_plus_plus::rspace::replay_rspace::ReplayRSpace;
23use f1r3fly_rspace_plus_plus::rspace::trace::event::{Consume, Produce, COMM};
24use f1r3fly_rspace_plus_plus::rspace::{
25 rspace::RSpace,
26 trace::event::{Event, IOEvent},
27};
28use rust::interpreter::env::Env;
29use rust::interpreter::system_processes::test_framework_contracts;
30use rust::interpreter::{
31 accounting::costs::Cost,
32 rho_runtime::{
33 bootstrap_registry as bootstrap_registry_internal, create_rho_runtime,
34 RhoRuntime as RhoRuntimeTrait, RhoRuntimeImpl,
35 },
36 system_processes::BlockData,
37};
38
39#[repr(C)]
40struct RhoRuntime {
41 runtime: Arc<Mutex<RhoRuntimeImpl>>,
42}
43
44#[repr(C)]
45struct ReplayRhoRuntime {
46 runtime: Arc<Mutex<RhoRuntimeImpl>>,
47}
48
49#[repr(C)]
50struct Space {
51 rspace: Mutex<RSpace<Par, BindPattern, ListParWithRandom, TaggedContinuation>>,
52}
53
54#[repr(C)]
55struct ReplaySpace {
56 replay_space: Mutex<ReplayRSpace<Par, BindPattern, ListParWithRandom, TaggedContinuation>>,
57}
58
59#[no_mangle]
62extern "C" fn evaluate(
63 runtime_ptr: *mut RhoRuntime,
64 params_ptr: *const u8,
65 params_bytes_len: usize,
66) -> *const u8 {
67 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
70 let params = EvaluateParams::decode(params_slice).unwrap();
71
72 let term = params.term;
73 let cost_proto = params.initial_phlo.unwrap();
74 let initial_phlo = Cost::create(cost_proto.value.into(), cost_proto.operation);
75 let normalizer_env = params.normalizer_env;
76 let rand_proto = params.random_state.unwrap();
77 let digest_proto = rand_proto.digest.unwrap();
78 let rand = Blake2b512Random {
83 digest: Blake2b512Block {
84 chain_value: digest_proto
85 .chain_value
86 .into_iter()
87 .map(|v| v.value)
88 .collect(),
89 t0: digest_proto.t0,
90 t1: digest_proto.t1,
91 },
92 last_block: rand_proto.last_block.into_iter().map(|v| v as i8).collect(),
93 path_view: rand_proto.path_view,
94 count_view: rand_proto.count_view.into_iter().map(|v| v.value).collect(),
95 hash_array: {
96 let mut array = [0i8; 64];
97 let vec = rand_proto.hash_array;
98 let i8_slice: &[i8] = unsafe { std::mem::transmute(&vec[..64]) };
99 array.copy_from_slice(i8_slice);
100 array
101 },
102 position: rand_proto.position,
103 path_position: rand_proto.path_position as usize,
104 };
105 let mut rho_runtime = unsafe { (*runtime_ptr).runtime.try_lock().unwrap() };
109 let rt = tokio::runtime::Runtime::new().unwrap();
110 let eval_result = rt.block_on(async {
111 rho_runtime
112 .evaluate(
113 &term,
114 initial_phlo,
115 normalizer_env.into_iter().collect(),
116 rand,
117 )
118 .await
119 .unwrap()
120 });
121
122 let eval_result_proto = EvaluateResultProto {
125 cost: Some(CostProto {
126 value: eval_result.cost.value,
127 operation: eval_result.cost.operation,
128 }),
129 errors: eval_result
130 .errors
131 .into_iter()
132 .map(|err| err.to_string())
133 .collect(),
134 mergeable: eval_result.mergeable.into_iter().collect(),
135 };
136
137 let mut bytes = eval_result_proto.encode_to_vec();
138 let len = bytes.len() as u32;
139 let len_bytes = len.to_le_bytes().to_vec();
140 let mut result = len_bytes;
141 result.append(&mut bytes);
142 Box::leak(result.into_boxed_slice()).as_ptr()
143}
144
145#[no_mangle]
146extern "C" fn inj(
147 runtime_ptr: *mut RhoRuntime,
148 params_ptr: *const u8,
149 params_bytes_len: usize,
150) -> () {
151 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
152 let params = InjParams::decode(params_slice).unwrap();
153
154 let par = params.par.unwrap();
155 let env_proto = params.env.unwrap();
156 let env = Env {
157 env_map: env_proto.env_map.into_iter().collect(),
158 level: env_proto.level,
159 shift: env_proto.shift,
160 };
161
162 let rand_proto = params.rand.unwrap();
163 let digest_proto = rand_proto.digest.unwrap();
164 let rand = Blake2b512Random {
165 digest: Blake2b512Block {
166 chain_value: digest_proto
167 .chain_value
168 .into_iter()
169 .map(|v| v.value)
170 .collect(),
171 t0: digest_proto.t0,
172 t1: digest_proto.t1,
173 },
174 last_block: rand_proto.last_block.into_iter().map(|v| v as i8).collect(),
175 path_view: rand_proto.path_view,
176 count_view: rand_proto.count_view.into_iter().map(|v| v.value).collect(),
177 hash_array: {
178 let mut array = [0i8; 64];
179 let vec = rand_proto.hash_array;
180 let i8_slice: &[i8] = unsafe { std::mem::transmute(&vec[..64]) };
181 array.copy_from_slice(i8_slice);
182 array
183 },
184 position: rand_proto.position,
185 path_position: rand_proto.path_position as usize,
186 };
187
188 let rho_runtime = unsafe { (*runtime_ptr).runtime.try_lock().unwrap() };
192 let rt = tokio::runtime::Runtime::new().unwrap();
193 rt.block_on(async { rho_runtime.inj(par, env, rand).await.unwrap() })
194}
195
196#[no_mangle]
197extern "C" fn create_soft_checkpoint(runtime_ptr: *mut RhoRuntime) -> *const u8 {
198 let runtime = unsafe { (*runtime_ptr).runtime.clone() };
200 let soft_checkpoint = runtime.try_lock().unwrap().create_soft_checkpoint();
201
202 let mut conts_map_entries: Vec<StoreStateContMapEntry> = Vec::new();
203 let mut installed_conts_map_entries: Vec<StoreStateInstalledContMapEntry> = Vec::new();
204 let mut data_map_entries: Vec<StoreStateDataMapEntry> = Vec::new();
205 let mut joins_map_entries: Vec<StoreStateJoinsMapEntry> = Vec::new();
206 let mut installed_joins_map_entries: Vec<StoreStateInstalledJoinsMapEntry> = Vec::new();
207
208 let hot_store_state = soft_checkpoint.cache_snapshot;
209
210 for (key, value) in hot_store_state.continuations.clone().into_iter() {
211 let wks: Vec<WaitingContinuationProto> = value
212 .into_iter()
213 .map(|wk| {
214 let res = WaitingContinuationProto {
215 patterns: wk.patterns,
216 continuation: Some(wk.continuation.clone()),
217 persist: wk.persist,
218 peeks: wk
219 .peeks
220 .into_iter()
221 .map(|peek| SortedSetElement { value: peek as i32 })
222 .collect(),
223 source: Some(ConsumeProto {
224 channel_hashes: wk
225 .source
226 .channel_hashes
227 .iter()
228 .map(|hash| hash.bytes())
229 .collect(),
230 hash: wk.source.hash.bytes(),
231 persistent: wk.source.persistent,
232 }),
233 };
234
235 res
236 })
237 .collect();
238
239 conts_map_entries.push(StoreStateContMapEntry { key, value: wks });
240 }
241
242 for (key, value) in hot_store_state.installed_continuations.clone().into_iter() {
243 let wk = WaitingContinuationProto {
244 patterns: value.patterns,
245 continuation: Some(value.continuation.clone()),
246 persist: value.persist,
247 peeks: value
248 .peeks
249 .into_iter()
250 .map(|peek| SortedSetElement { value: peek as i32 })
251 .collect(),
252 source: Some(ConsumeProto {
253 channel_hashes: value
254 .source
255 .channel_hashes
256 .iter()
257 .map(|hash| hash.bytes())
258 .collect(),
259 hash: value.source.hash.bytes(),
260 persistent: value.source.persistent,
261 }),
262 };
263
264 installed_conts_map_entries.push(StoreStateInstalledContMapEntry {
265 key,
266 value: Some(wk),
267 });
268 }
269
270 for (key, value) in hot_store_state.data.clone().into_iter() {
271 let datums = value
272 .into_iter()
273 .map(|datum| DatumProto {
274 a: Some(datum.a),
275 persist: datum.persist,
276 source: Some(ProduceProto {
277 channel_hash: datum.source.channel_hash.bytes(),
278 hash: datum.source.hash.bytes(),
279 persistent: datum.source.persistent,
280 is_deterministic: datum.source.is_deterministic,
281 output_value: datum.source.output_value,
282 }),
283 })
284 .collect();
285
286 data_map_entries.push(StoreStateDataMapEntry {
287 key: Some(key),
288 value: datums,
289 });
290 }
291
292 for (key, value) in hot_store_state.joins.clone().into_iter() {
293 let joins = value.into_iter().map(|join| JoinProto { join }).collect();
294
295 joins_map_entries.push(StoreStateJoinsMapEntry {
296 key: Some(key),
297 value: joins,
298 });
299 }
300
301 for (key, value) in hot_store_state.installed_joins.clone().into_iter() {
302 let joins = value.into_iter().map(|join| JoinProto { join }).collect();
303
304 installed_joins_map_entries.push(StoreStateInstalledJoinsMapEntry {
305 key: Some(key),
306 value: joins,
307 });
308 }
309
310 let hot_store_state_proto = HotStoreStateProto {
311 continuations: conts_map_entries,
312 installed_continuations: installed_conts_map_entries,
313 data: data_map_entries,
314 joins: joins_map_entries,
315 installed_joins: installed_joins_map_entries,
316 };
317
318 let log = soft_checkpoint.log;
319 let log_proto: Vec<EventProto> = log
320 .into_iter()
321 .map(|event| match event {
322 Event::Comm(comm) => {
323 let comm_proto = CommProto {
324 consume: {
325 Some(ConsumeProto {
326 channel_hashes: comm
327 .consume
328 .channel_hashes
329 .iter()
330 .map(|hash| hash.bytes())
331 .collect(),
332 hash: comm.consume.hash.bytes(),
333 persistent: comm.consume.persistent,
334 })
335 },
336 produces: {
337 comm.produces
338 .into_iter()
339 .map(|produce| ProduceProto {
340 channel_hash: produce.channel_hash.bytes(),
341 hash: produce.hash.bytes(),
342 persistent: produce.persistent,
343 is_deterministic: produce.is_deterministic,
344 output_value: produce.output_value,
345 })
346 .collect()
347 },
348 peeks: {
349 comm.peeks
350 .into_iter()
351 .map(|peek| SortedSetElement { value: peek as i32 })
352 .collect()
353 },
354 times_repeated: {
355 let mut produce_counter_map_entries: Vec<ProduceCounterMapEntry> =
356 Vec::new();
357 for (key, value) in comm.times_repeated {
358 let produce = ProduceProto {
359 channel_hash: key.channel_hash.bytes(),
360 hash: key.hash.bytes(),
361 persistent: key.persistent,
362 is_deterministic: key.is_deterministic,
363 output_value: key.output_value,
364 };
365
366 produce_counter_map_entries.push(ProduceCounterMapEntry {
367 key: Some(produce),
368 value,
369 });
370 }
371 produce_counter_map_entries
372 },
373 };
374
375 EventProto {
376 event_type: Some(event_proto::EventType::Comm(comm_proto)),
377 }
378 }
379 Event::IoEvent(io_event) => match io_event {
380 IOEvent::Produce(produce) => {
381 let produce_proto = ProduceProto {
382 channel_hash: produce.channel_hash.bytes(),
383 hash: produce.hash.bytes(),
384 persistent: produce.persistent,
385 is_deterministic: produce.is_deterministic,
386 output_value: produce.output_value,
387 };
388 EventProto {
389 event_type: Some(event_proto::EventType::IoEvent(IoEventProto {
390 io_event_type: Some(io_event_proto::IoEventType::Produce(
391 produce_proto,
392 )),
393 })),
394 }
395 }
396 IOEvent::Consume(consume) => {
397 let consume_proto = ConsumeProto {
398 channel_hashes: consume
399 .channel_hashes
400 .iter()
401 .map(|hash| hash.bytes())
402 .collect(),
403 hash: consume.hash.bytes(),
404 persistent: consume.persistent,
405 };
406 EventProto {
407 event_type: Some(event_proto::EventType::IoEvent(IoEventProto {
408 io_event_type: Some(io_event_proto::IoEventType::Consume(
409 consume_proto,
410 )),
411 })),
412 }
413 }
414 },
415 })
416 .collect();
417
418 let mut produce_counter_map_entries: Vec<ProduceCounterMapEntry> = Vec::new();
419 let produce_counter_map = soft_checkpoint.produce_counter;
420
421 for (key, value) in produce_counter_map {
422 let produce = ProduceProto {
423 channel_hash: key.channel_hash.bytes(),
424 hash: key.hash.bytes(),
425 persistent: key.persistent,
426 is_deterministic: key.is_deterministic,
427 output_value: key.output_value,
428 };
429
430 produce_counter_map_entries.push(ProduceCounterMapEntry {
431 key: Some(produce),
432 value,
433 });
434 }
435
436 let soft_checkpoint_proto = SoftCheckpointProto {
437 cache_snapshot: Some(hot_store_state_proto),
438 log: log_proto,
439 produce_counter: produce_counter_map_entries,
440 };
441
442 let mut bytes = soft_checkpoint_proto.encode_to_vec();
443 let len = bytes.len() as u32;
444 let len_bytes = len.to_le_bytes().to_vec();
445 let mut result = len_bytes;
446 result.append(&mut bytes);
447 Box::leak(result.into_boxed_slice()).as_ptr()
448}
449
450#[no_mangle]
451extern "C" fn revert_to_soft_checkpoint(
452 runtime_ptr: *mut RhoRuntime,
453 payload_pointer: *const u8,
454 payload_bytes_len: usize,
455) -> () {
456 let payload_slice = unsafe { std::slice::from_raw_parts(payload_pointer, payload_bytes_len) };
457 let soft_checkpoint_proto = SoftCheckpointProto::decode(payload_slice).unwrap();
458 let cache_snapshot_proto = soft_checkpoint_proto.cache_snapshot.unwrap();
459
460 let conts_map = new_dashmap();
461 for map_entry in cache_snapshot_proto.continuations {
462 let key = map_entry.key;
463 let value = map_entry
464 .value
465 .into_iter()
466 .map(|cont_proto| WaitingContinuation {
467 patterns: cont_proto.patterns,
468 continuation: cont_proto.continuation.unwrap(),
469 persist: cont_proto.persist,
470 peeks: cont_proto
471 .peeks
472 .iter()
473 .map(|element| element.value)
474 .collect(),
475 source: {
476 let consume_proto = cont_proto.source.unwrap();
477 Consume {
478 channel_hashes: consume_proto
479 .channel_hashes
480 .iter()
481 .map(|hash_bytes| Blake2b256Hash::from_bytes(hash_bytes.to_vec()))
482 .collect(),
483 hash: Blake2b256Hash::from_bytes(consume_proto.hash),
484 persistent: consume_proto.persistent,
485 }
486 },
487 })
488 .collect();
489
490 conts_map.insert(key, value);
491 }
492
493 let installed_conts_map = new_dashmap();
494 for map_entry in cache_snapshot_proto.installed_continuations {
495 let key = map_entry.key;
496 let wk_proto = map_entry.value.unwrap();
497 let value = WaitingContinuation {
498 patterns: wk_proto.patterns,
499 continuation: wk_proto.continuation.unwrap(),
500 persist: wk_proto.persist,
501 peeks: wk_proto.peeks.iter().map(|element| element.value).collect(),
502 source: {
503 let consume_proto = wk_proto.source.unwrap();
504 Consume {
505 channel_hashes: consume_proto
506 .channel_hashes
507 .iter()
508 .map(|hash_bytes| Blake2b256Hash::from_bytes(hash_bytes.to_vec()))
509 .collect(),
510 hash: Blake2b256Hash::from_bytes(consume_proto.hash),
511 persistent: consume_proto.persistent,
512 }
513 },
514 };
515
516 installed_conts_map.insert(key, value);
517 }
518
519 let datums_map = new_dashmap();
520 for map_entry in cache_snapshot_proto.data {
521 let key = map_entry.key.unwrap();
522 let value = map_entry
523 .value
524 .into_iter()
525 .map(|datum_proto| Datum {
526 a: datum_proto.a.unwrap(),
527 persist: datum_proto.persist,
528 source: {
529 let produce_proto = datum_proto.source.unwrap();
530 Produce {
531 channel_hash: Blake2b256Hash::from_bytes(produce_proto.channel_hash),
532 hash: Blake2b256Hash::from_bytes(produce_proto.hash),
533 persistent: produce_proto.persistent,
534 is_deterministic: produce_proto.is_deterministic,
535 output_value: produce_proto.output_value,
536 }
537 },
538 })
539 .collect();
540
541 datums_map.insert(key, value);
542 }
543
544 let joins_map = new_dashmap();
545 for map_entry in cache_snapshot_proto.joins {
546 let key = map_entry.key.unwrap();
547 let value = map_entry
548 .value
549 .into_iter()
550 .map(|join_proto| join_proto.join)
551 .collect();
552
553 joins_map.insert(key, value);
554 }
555
556 let installed_joins_map = new_dashmap();
557 for map_entry in cache_snapshot_proto.installed_joins {
558 let key = map_entry.key.unwrap();
559 let value = map_entry
560 .value
561 .into_iter()
562 .map(|join_proto| join_proto.join)
563 .collect();
564
565 installed_joins_map.insert(key, value);
566 }
567
568 let log: Vec<Event> = soft_checkpoint_proto
569 .log
570 .into_iter()
571 .map(|log_entry| match log_entry.event_type.unwrap() {
572 event_proto::EventType::Comm(comm_proto) => {
573 let consume_proto = comm_proto.consume.unwrap();
574 let comm = COMM {
575 consume: {
576 Consume {
577 channel_hashes: {
578 consume_proto
579 .channel_hashes
580 .iter()
581 .map(|hash| Blake2b256Hash::from_bytes(hash.clone()))
582 .collect()
583 },
584 hash: Blake2b256Hash::from_bytes(consume_proto.hash),
585 persistent: consume_proto.persistent,
586 }
587 },
588 produces: {
589 comm_proto
590 .produces
591 .into_iter()
592 .map(|produce_proto| Produce {
593 channel_hash: Blake2b256Hash::from_bytes(
594 produce_proto.channel_hash,
595 ),
596 hash: Blake2b256Hash::from_bytes(produce_proto.hash),
597 persistent: produce_proto.persistent,
598 is_deterministic: produce_proto.is_deterministic,
599 output_value: produce_proto.output_value,
600 })
601 .collect()
602 },
603 peeks: {
604 comm_proto
605 .peeks
606 .iter()
607 .map(|element| element.value)
608 .collect()
609 },
610 times_repeated: {
611 comm_proto
612 .times_repeated
613 .into_iter()
614 .map(|map_entry| {
615 let key_proto = map_entry.key.unwrap();
616 let produce = Produce {
617 channel_hash: Blake2b256Hash::from_bytes(
618 key_proto.channel_hash,
619 ),
620 hash: Blake2b256Hash::from_bytes(key_proto.hash),
621 persistent: key_proto.persistent,
622 is_deterministic: key_proto.is_deterministic,
623 output_value: key_proto.output_value,
624 };
625
626 let value = map_entry.value;
627
628 (produce, value)
629 })
630 .collect()
631 },
632 };
633 Event::Comm(comm)
634 }
635 event_proto::EventType::IoEvent(io_event) => match io_event.io_event_type.unwrap() {
636 io_event_proto::IoEventType::Produce(produce_proto) => {
637 let produce = Produce {
638 channel_hash: Blake2b256Hash::from_bytes(produce_proto.channel_hash),
639 hash: Blake2b256Hash::from_bytes(produce_proto.hash),
640 persistent: produce_proto.persistent,
641 is_deterministic: produce_proto.is_deterministic,
642 output_value: produce_proto.output_value,
643 };
644 Event::IoEvent(IOEvent::Produce(produce))
645 }
646 io_event_proto::IoEventType::Consume(consume_proto) => {
647 let consume = Consume {
648 channel_hashes: {
649 consume_proto
650 .channel_hashes
651 .iter()
652 .map(|hash| Blake2b256Hash::from_bytes(hash.clone()))
653 .collect()
654 },
655 hash: Blake2b256Hash::from_bytes(consume_proto.hash),
656 persistent: consume_proto.persistent,
657 };
658 Event::IoEvent(IOEvent::Consume(consume))
659 }
660 },
661 })
662 .collect();
663
664 let produce_counter_map: BTreeMap<Produce, i32> = soft_checkpoint_proto
665 .produce_counter
666 .into_iter()
667 .map(|map_entry| {
668 let key_proto = map_entry.key.unwrap();
669 let produce = Produce {
670 channel_hash: Blake2b256Hash::from_bytes(key_proto.channel_hash),
671 hash: Blake2b256Hash::from_bytes(key_proto.hash),
672 persistent: key_proto.persistent,
673 is_deterministic: key_proto.is_deterministic,
674 output_value: key_proto.output_value,
675 };
676
677 let value = map_entry.value;
678
679 (produce, value)
680 })
681 .collect();
682
683 let cache_snapshot = HotStoreState {
684 continuations: conts_map,
685 installed_continuations: installed_conts_map,
686 data: datums_map,
687 joins: joins_map,
688 installed_joins: installed_joins_map,
689 };
690
691 let soft_checkpoint = SoftCheckpoint {
692 cache_snapshot,
693 log,
694 produce_counter: produce_counter_map,
695 };
696
697 let runtime = unsafe { (*runtime_ptr).runtime.clone() };
698
699 runtime
700 .try_lock()
701 .unwrap()
702 .revert_to_soft_checkpoint(soft_checkpoint);
703}
704
705#[no_mangle]
706extern "C" fn create_checkpoint(runtime_ptr: *mut RhoRuntime) -> *const u8 {
707 let runtime = unsafe { (*runtime_ptr).runtime.clone() };
708 let checkpoint = runtime.try_lock().unwrap().create_checkpoint();
709
710 let log = checkpoint.log;
711 let log_proto: Vec<EventProto> = log
712 .into_iter()
713 .map(|event| match event {
714 Event::Comm(comm) => {
715 let comm_proto = CommProto {
716 consume: {
717 Some(ConsumeProto {
718 channel_hashes: comm
719 .consume
720 .channel_hashes
721 .iter()
722 .map(|hash| hash.bytes())
723 .collect(),
724 hash: comm.consume.hash.bytes(),
725 persistent: comm.consume.persistent,
726 })
727 },
728 produces: {
729 comm.produces
730 .into_iter()
731 .map(|produce| ProduceProto {
732 channel_hash: produce.channel_hash.bytes(),
733 hash: produce.hash.bytes(),
734 persistent: produce.persistent,
735 is_deterministic: produce.is_deterministic,
736 output_value: produce.output_value,
737 })
738 .collect()
739 },
740 peeks: {
741 comm.peeks
742 .into_iter()
743 .map(|peek| SortedSetElement { value: peek as i32 })
744 .collect()
745 },
746 times_repeated: {
747 let mut produce_counter_map_entries: Vec<ProduceCounterMapEntry> =
748 Vec::new();
749 for (key, value) in comm.times_repeated {
750 let produce = ProduceProto {
751 channel_hash: key.channel_hash.bytes(),
752 hash: key.hash.bytes(),
753 persistent: key.persistent,
754 is_deterministic: key.is_deterministic,
755 output_value: key.output_value,
756 };
757
758 produce_counter_map_entries.push(ProduceCounterMapEntry {
759 key: Some(produce),
760 value,
761 });
762 }
763 produce_counter_map_entries
764 },
765 };
766
767 EventProto {
768 event_type: Some(event_proto::EventType::Comm(comm_proto)),
769 }
770 }
771 Event::IoEvent(io_event) => match io_event {
772 IOEvent::Produce(produce) => {
773 let produce_proto = ProduceProto {
774 channel_hash: produce.channel_hash.bytes(),
775 hash: produce.hash.bytes(),
776 persistent: produce.persistent,
777 is_deterministic: produce.is_deterministic,
778 output_value: produce.output_value,
779 };
780 EventProto {
781 event_type: Some(event_proto::EventType::IoEvent(IoEventProto {
782 io_event_type: Some(io_event_proto::IoEventType::Produce(
783 produce_proto,
784 )),
785 })),
786 }
787 }
788 IOEvent::Consume(consume) => {
789 let consume_proto = ConsumeProto {
790 channel_hashes: consume
791 .channel_hashes
792 .iter()
793 .map(|hash| hash.bytes())
794 .collect(),
795 hash: consume.hash.bytes(),
796 persistent: consume.persistent,
797 };
798 EventProto {
799 event_type: Some(event_proto::EventType::IoEvent(IoEventProto {
800 io_event_type: Some(io_event_proto::IoEventType::Consume(
801 consume_proto,
802 )),
803 })),
804 }
805 }
806 },
807 })
808 .collect();
809
810 let checkpoint_proto = CheckpointProto {
811 root: checkpoint.root.bytes(),
812 log: log_proto,
813 };
814
815 let mut bytes = checkpoint_proto.encode_to_vec();
816 let len = bytes.len() as u32;
817 let len_bytes = len.to_le_bytes().to_vec();
818 let mut result = len_bytes;
819 result.append(&mut bytes);
820 Box::leak(result.into_boxed_slice()).as_ptr()
821}
822
823#[no_mangle]
824extern "C" fn consume_result(
825 runtime_ptr: *mut RhoRuntime,
826 params_ptr: *const u8,
827 params_bytes_len: usize,
828) -> *const u8 {
829 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
830 let consume_result_params = ConsumeResultParams::decode(params_slice).unwrap();
831
832 let channel = consume_result_params.channel;
833 let pattern = consume_result_params.pattern;
834
835 let consume_result_return = unsafe {
836 (*runtime_ptr)
837 .runtime
838 .try_lock()
839 .unwrap()
840 .consume_result(channel, pattern)
841 .unwrap()
842 };
843
844 match consume_result_return {
845 None => std::ptr::null(),
846 Some((tagged_cont, datums)) => {
847 let consume_result_return_proto = ConsumeResultReturn {
848 tagged_cont: Some(tagged_cont),
849 datums,
850 };
851
852 let mut bytes = consume_result_return_proto.encode_to_vec();
853 let len = bytes.len() as u32;
854 let len_bytes = len.to_le_bytes().to_vec();
855 let mut result = len_bytes;
856 result.append(&mut bytes);
857 Box::leak(result.into_boxed_slice()).as_ptr()
858 }
859 }
860}
861
862#[no_mangle]
863extern "C" fn reset(
864 runtime_ptr: *mut RhoRuntime,
865 root_pointer: *const u8,
866 root_bytes_len: usize,
867) -> () {
868 let root_slice = unsafe { std::slice::from_raw_parts(root_pointer, root_bytes_len) };
871 let root = Blake2b256Hash::from_bytes(root_slice.to_vec());
872
873 let runtime = unsafe { (*runtime_ptr).runtime.clone() };
874 runtime.try_lock().unwrap().reset(root);
875}
876
877#[no_mangle]
878extern "C" fn get_data(
879 runtime_ptr: *mut RhoRuntime,
880 channel_pointer: *const u8,
881 channel_bytes_len: usize,
882) -> *const u8 {
883 let channel_slice = unsafe { std::slice::from_raw_parts(channel_pointer, channel_bytes_len) };
884 let channel = Par::decode(channel_slice).unwrap();
885
886 let datums = unsafe { (*runtime_ptr).runtime.try_lock().unwrap().get_data(channel) };
890
891 let datums_protos: Vec<DatumProto> = datums
894 .into_iter()
895 .map(|datum| DatumProto {
896 a: Some(datum.a),
897 persist: datum.persist,
898 source: Some(ProduceProto {
899 channel_hash: datum.source.channel_hash.bytes(),
900 hash: datum.source.hash.bytes(),
901 persistent: datum.source.persistent,
902 is_deterministic: datum.source.is_deterministic,
903 output_value: datum.source.output_value,
904 }),
905 })
906 .collect();
907
908 let datums_proto = DatumsProto {
909 datums: datums_protos,
910 };
911
912 let mut bytes = datums_proto.encode_to_vec();
913 let len = bytes.len() as u32;
914 let len_bytes = len.to_le_bytes().to_vec();
915 let mut result = len_bytes;
916 result.append(&mut bytes);
917 Box::leak(result.into_boxed_slice()).as_ptr()
918}
919
920#[no_mangle]
921extern "C" fn get_joins(
922 runtime_ptr: *mut RhoRuntime,
923 channel_pointer: *const u8,
924 channel_bytes_len: usize,
925) -> *const u8 {
926 let channel_slice = unsafe { std::slice::from_raw_parts(channel_pointer, channel_bytes_len) };
927 let channel = Par::decode(channel_slice).unwrap();
928
929 let joins = unsafe {
930 (*runtime_ptr)
931 .runtime
932 .try_lock()
933 .unwrap()
934 .get_joins(channel)
935 };
936
937 let vec_join: Vec<JoinProto> = joins.into_iter().map(|join| JoinProto { join }).collect();
938 let joins_proto = JoinsProto { joins: vec_join };
939
940 let mut bytes = joins_proto.encode_to_vec();
941 let len = bytes.len() as u32;
942 let len_bytes = len.to_le_bytes().to_vec();
943 let mut result = len_bytes;
944 result.append(&mut bytes);
945 Box::leak(result.into_boxed_slice()).as_ptr()
946}
947
948#[no_mangle]
949extern "C" fn get_waiting_continuations(
950 runtime_ptr: *mut RhoRuntime,
951 channels_pointer: *const u8,
952 channels_bytes_len: usize,
953) -> *const u8 {
954 let channels_slice =
955 unsafe { std::slice::from_raw_parts(channels_pointer, channels_bytes_len) };
956 let channels_proto = ChannelsProto::decode(channels_slice).unwrap();
957
958 let wks = unsafe {
959 (*runtime_ptr)
960 .runtime
961 .try_lock()
962 .unwrap()
963 .get_continuations(channels_proto.channels)
964 };
965
966 let wks_protos: Vec<WaitingContinuationProto> = wks
967 .into_iter()
968 .map(|wk| {
969 let res = WaitingContinuationProto {
970 patterns: wk.patterns,
971 continuation: Some(wk.continuation.clone()),
972 persist: wk.persist,
973 peeks: wk
974 .peeks
975 .into_iter()
976 .map(|peek| SortedSetElement { value: peek as i32 })
977 .collect(),
978 source: Some(ConsumeProto {
979 channel_hashes: wk
980 .source
981 .channel_hashes
982 .iter()
983 .map(|hash| hash.bytes())
984 .collect(),
985 hash: wk.source.hash.bytes(),
986 persistent: wk.source.persistent,
987 }),
988 };
989
990 res
991 })
992 .collect();
993
994 let wks_proto = WaitingContinuationsProto { wks: wks_protos };
995
996 let mut bytes = wks_proto.encode_to_vec();
997 let len = bytes.len() as u32;
998 let len_bytes = len.to_le_bytes().to_vec();
999 let mut result = len_bytes;
1000 result.append(&mut bytes);
1001 Box::leak(result.into_boxed_slice()).as_ptr()
1002}
1003
1004#[no_mangle]
1005extern "C" fn set_block_data(
1006 runtime_ptr: *mut RhoRuntime,
1007 params_ptr: *const u8,
1008 params_bytes_len: usize,
1009) -> () {
1010 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
1011 let params = BlockDataProto::decode(params_slice).unwrap();
1012 let block_data = BlockData {
1013 time_stamp: params.time_stamp as i64,
1014 block_number: params.block_number as i64,
1015 sender: PublicKey::from_bytes(¶ms.public_key),
1016 seq_num: params.seq_num,
1017 };
1018
1019 unsafe {
1020 (*runtime_ptr)
1021 .runtime
1022 .try_lock()
1023 .unwrap()
1024 .set_block_data(block_data);
1025 }
1026}
1027
1028#[no_mangle]
1029extern "C" fn set_invalid_blocks(
1030 runtime_ptr: *mut RhoRuntime,
1031 params_ptr: *const u8,
1032 params_bytes_len: usize,
1033) -> () {
1034 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
1035 let params = InvalidBlocksProto::decode(params_slice).unwrap();
1036 let invalid_blocks = params
1037 .invalid_blocks
1038 .into_iter()
1039 .map(|block| {
1040 (block.block_hash, block.validator)
1041 })
1042 .collect();
1043
1044 unsafe {
1045 (*runtime_ptr)
1046 .runtime
1047 .try_lock()
1048 .unwrap()
1049 .set_invalid_blocks(invalid_blocks);
1050 }
1051}
1052
1053#[no_mangle]
1054extern "C" fn get_hot_changes(runtime_ptr: *mut RhoRuntime) -> *const u8 {
1055 let runtime = unsafe { (*runtime_ptr).runtime.clone() };
1056 let hot_store_mapped = runtime.try_lock().unwrap().get_hot_changes();
1057
1058 let mut map_entries: Vec<StoreToMapEntry> = Vec::new();
1059
1060 for (key, value) in hot_store_mapped {
1061 let datums = value
1062 .data
1063 .into_iter()
1064 .map(|datum| DatumProto {
1065 a: Some(datum.a),
1066 persist: datum.persist,
1067 source: Some(ProduceProto {
1068 channel_hash: datum.source.channel_hash.bytes(),
1069 hash: datum.source.hash.bytes(),
1070 persistent: datum.source.persistent,
1071 is_deterministic: datum.source.is_deterministic,
1072 output_value: datum.source.output_value,
1073 }),
1074 })
1075 .collect();
1076
1077 let wks = value
1078 .wks
1079 .into_iter()
1080 .map(|wk| {
1081 let res = WaitingContinuationProto {
1082 patterns: wk.patterns,
1083 continuation: Some(wk.continuation.clone()),
1084 persist: wk.persist,
1085 peeks: wk
1086 .peeks
1087 .into_iter()
1088 .map(|peek| SortedSetElement { value: peek as i32 })
1089 .collect(),
1090 source: Some(ConsumeProto {
1091 channel_hashes: wk
1092 .source
1093 .channel_hashes
1094 .iter()
1095 .map(|hash| hash.bytes())
1096 .collect(),
1097 hash: wk.source.hash.bytes(),
1098 persistent: wk.source.persistent,
1099 }),
1100 };
1101
1102 res
1103 })
1104 .collect();
1105
1106 let value = StoreToMapValue { data: datums, wks };
1107 map_entries.push(StoreToMapEntry {
1108 key,
1109 value: Some(value),
1110 });
1111 }
1112
1113 let to_map_result = StoreToMapResult { map_entries };
1114
1115 let mut bytes = to_map_result.encode_to_vec();
1116 let len = bytes.len() as u32;
1117 let len_bytes = len.to_le_bytes().to_vec();
1118 let mut result = len_bytes;
1119 result.append(&mut bytes);
1120 Box::leak(result.into_boxed_slice()).as_ptr()
1121}
1122
1123#[no_mangle]
1124extern "C" fn set_cost_to_max(runtime_ptr: *mut RhoRuntime) -> () {
1125 unsafe {
1126 (*runtime_ptr)
1127 .runtime
1128 .try_lock()
1129 .unwrap()
1130 .cost
1131 .set(Cost::unsafe_max());
1132 }
1133}
1134
1135#[no_mangle]
1138extern "C" fn rig(
1139 runtime_ptr: *mut ReplayRhoRuntime,
1140 log_pointer: *const u8,
1141 log_bytes_len: usize,
1142) -> () {
1143 let log_slice = unsafe { std::slice::from_raw_parts(log_pointer, log_bytes_len) };
1144 let log_proto = LogProto::decode(log_slice).unwrap();
1145
1146 let log: Vec<Event> = log_proto
1147 .log
1148 .into_iter()
1149 .map(|log_entry| match log_entry.event_type.unwrap() {
1150 event_proto::EventType::Comm(comm_proto) => {
1151 let consume_proto = comm_proto.consume.unwrap();
1152 let comm = COMM {
1153 consume: {
1154 Consume {
1155 channel_hashes: {
1156 consume_proto
1157 .channel_hashes
1158 .iter()
1159 .map(|hash| Blake2b256Hash::from_bytes(hash.clone()))
1160 .collect()
1161 },
1162 hash: Blake2b256Hash::from_bytes(consume_proto.hash),
1163 persistent: consume_proto.persistent,
1164 }
1165 },
1166 produces: {
1167 comm_proto
1168 .produces
1169 .into_iter()
1170 .map(|produce_proto| Produce {
1171 channel_hash: Blake2b256Hash::from_bytes(
1172 produce_proto.channel_hash,
1173 ),
1174 hash: Blake2b256Hash::from_bytes(produce_proto.hash),
1175 persistent: produce_proto.persistent,
1176 is_deterministic: produce_proto.is_deterministic,
1177 output_value: produce_proto.output_value,
1178 })
1179 .collect()
1180 },
1181 peeks: {
1182 comm_proto
1183 .peeks
1184 .iter()
1185 .map(|element| element.value)
1186 .collect()
1187 },
1188 times_repeated: {
1189 comm_proto
1190 .times_repeated
1191 .into_iter()
1192 .map(|map_entry| {
1193 let key_proto = map_entry.key.unwrap();
1194 let produce = Produce {
1195 channel_hash: Blake2b256Hash::from_bytes(
1196 key_proto.channel_hash,
1197 ),
1198 hash: Blake2b256Hash::from_bytes(key_proto.hash),
1199 persistent: key_proto.persistent,
1200 is_deterministic: key_proto.is_deterministic,
1201 output_value: key_proto.output_value,
1202 };
1203
1204 let value = map_entry.value;
1205
1206 (produce, value)
1207 })
1208 .collect()
1209 },
1210 };
1211 Event::Comm(comm)
1212 }
1213 event_proto::EventType::IoEvent(io_event) => match io_event.io_event_type.unwrap() {
1214 io_event_proto::IoEventType::Produce(produce_proto) => {
1215 let produce = Produce {
1216 channel_hash: Blake2b256Hash::from_bytes(produce_proto.channel_hash),
1217 hash: Blake2b256Hash::from_bytes(produce_proto.hash),
1218 persistent: produce_proto.persistent,
1219 is_deterministic: produce_proto.is_deterministic,
1220 output_value: produce_proto.output_value,
1221 };
1222 Event::IoEvent(IOEvent::Produce(produce))
1223 }
1224 io_event_proto::IoEventType::Consume(consume_proto) => {
1225 let consume = Consume {
1226 channel_hashes: {
1227 consume_proto
1228 .channel_hashes
1229 .iter()
1230 .map(|hash| Blake2b256Hash::from_bytes(hash.clone()))
1231 .collect()
1232 },
1233 hash: Blake2b256Hash::from_bytes(consume_proto.hash),
1234 persistent: consume_proto.persistent,
1235 };
1236 Event::IoEvent(IOEvent::Consume(consume))
1237 }
1238 },
1239 })
1240 .collect();
1241
1242 unsafe {
1243 (*runtime_ptr).runtime.try_lock().unwrap().rig(log).unwrap();
1244 }
1245}
1246
1247#[no_mangle]
1248extern "C" fn check_replay_data(runtime_ptr: *mut ReplayRhoRuntime) -> () {
1249 unsafe {
1250 (*runtime_ptr)
1251 .runtime
1252 .try_lock()
1253 .unwrap()
1254 .check_replay_data()
1255 .unwrap();
1256 }
1257}
1258
1259#[no_mangle]
1260extern "C" fn create_runtime(
1261 rspace_ptr: *mut Space,
1262 params_ptr: *const u8,
1263 params_bytes_len: usize,
1264) -> *mut RhoRuntime {
1265 let rspace = unsafe { (*rspace_ptr).rspace.try_lock().unwrap().clone() };
1266
1267 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
1268 let params = CreateRuntimeParams::decode(params_slice).unwrap();
1269
1270 let mergeable_tag_name = params.mergeable_tag_name.unwrap();
1271 let init_registry = params.init_registry;
1272 if params.rho_spec_system_processes {
1273 panic!("ERROR: There are additional system processes being passed to the rust rho_runtime that are not being handled.")
1274 };
1275
1276 let tokio_runtime = tokio::runtime::Runtime::new().unwrap();
1277 let rho_runtime = tokio_runtime.block_on(async {
1278 create_rho_runtime(rspace, mergeable_tag_name, init_registry, &mut Vec::new()).await
1279 });
1280
1281 Box::into_raw(Box::new(RhoRuntime {
1282 runtime: rho_runtime,
1283 }))
1284}
1285
1286#[no_mangle]
1287extern "C" fn create_runtime_with_test_framework(
1288 rspace_ptr: *mut Space,
1289 params_ptr: *const u8,
1290 params_bytes_len: usize,
1291) -> *mut RhoRuntime {
1292 let rspace = unsafe { (*rspace_ptr).rspace.try_lock().unwrap().clone() };
1293
1294 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
1295 let params = CreateRuntimeParams::decode(params_slice).unwrap();
1296
1297 let mergeable_tag_name = params.mergeable_tag_name.unwrap();
1298 let init_registry = params.init_registry;
1299 let mut extra_system_processes = if params.rho_spec_system_processes {
1300 test_framework_contracts()
1301 } else {
1302 Vec::new()
1303 };
1304
1305 let tokio_runtime = tokio::runtime::Runtime::new().unwrap();
1306 let rho_runtime = tokio_runtime.block_on(async {
1307 create_rho_runtime(
1308 rspace,
1309 mergeable_tag_name,
1310 init_registry,
1311 &mut extra_system_processes,
1312 )
1313 .await
1314 });
1315
1316 Box::into_raw(Box::new(RhoRuntime {
1317 runtime: rho_runtime,
1318 }))
1319}
1320
1321#[no_mangle]
1322extern "C" fn create_replay_runtime(
1323 replay_space_ptr: *mut ReplaySpace,
1324 params_ptr: *const u8,
1325 params_bytes_len: usize,
1326) -> *mut ReplayRhoRuntime {
1327 let rspace = unsafe { (*replay_space_ptr).replay_space.try_lock().unwrap().clone() };
1328
1329 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
1330 let params = CreateRuntimeParams::decode(params_slice).unwrap();
1331
1332 let mergeable_tag_name = params.mergeable_tag_name.unwrap();
1333 let init_registry = params.init_registry;
1334 if params.rho_spec_system_processes {
1335 panic!("ERROR: There are additional system processes being passed to the rust rho_runtime that are not being handled.")
1336 };
1337
1338 let tokio_runtime = tokio::runtime::Runtime::new().unwrap();
1339 let replay_rho_runtime = tokio_runtime.block_on(async {
1340 create_rho_runtime(rspace, mergeable_tag_name, init_registry, &mut Vec::new()).await
1341 });
1342
1343 Box::into_raw(Box::new(ReplayRhoRuntime {
1344 runtime: replay_rho_runtime,
1345 }))
1346}
1347
1348#[no_mangle]
1349extern "C" fn bootstrap_registry(runtime_ptr: *mut RhoRuntime) -> () {
1350 let runtime = unsafe { (*runtime_ptr).runtime.clone() };
1351 let tokio_runtime = tokio::runtime::Runtime::new().unwrap();
1352 tokio_runtime.block_on(async {
1353 bootstrap_registry_internal(runtime).await;
1354 });
1355}
1356
1357#[no_mangle]
1358extern "C" fn source_to_adt(params_ptr: *const u8, params_bytes_len: usize) -> *const u8 {
1359 let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
1361 let params = SourceToAdtParams::decode(params_slice).unwrap();
1362
1363 let result = match Compiler::source_to_adt_with_normalizer_env(
1365 ¶ms.source,
1366 params.normalizer_env.into_iter().collect(),
1367 ) {
1368 Ok(par) => {
1369 par
1371 }
1372 Err(error) => {
1373 println!("source_to_adt rust side error {:?}", error);
1374 return std::ptr::null();
1375 }
1376 };
1377
1378 let mut result_bytes = result.encode_to_vec();
1380 let len = result_bytes.len() as u32;
1381 let len_bytes = len.to_le_bytes().to_vec();
1382
1383 let mut full_result = len_bytes;
1385 full_result.append(&mut result_bytes);
1386
1387 Box::leak(full_result.into_boxed_slice()).as_ptr()
1389}