f1r3fly_rholang/
lib.rs

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/* RHO RUNTIME */
60
61#[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    // println!("\nhit rust lib evaluate");
68
69    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    // println!(
79    //     "\nrandPathPosition in rust evaluate: {}",
80    //     rand_proto.path_position
81    // );
82    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    // println!("\nrand in rust evaluate: ");
106    // rand.debug_str();
107
108    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    // println!("\neval_result: {:?}", eval_result);
123
124    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    // println!("\nrand in rust inj: ");
189    // rand.debug_str();
190
191    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    // println!("\nhit rust lib create_soft_checkpoint");
199    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    // println!("\nHit reset");
869
870    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 rt = tokio::runtime::Runtime::new().unwrap();
887    // let datums =
888    //     rt.block_on(async { unsafe { (*runtime_ptr).runtime.try_lock().unwrap().get_data(channel).await } });
889    let datums = unsafe { (*runtime_ptr).runtime.try_lock().unwrap().get_data(channel) };
890
891    // println!("\ndatums in rust get_data: {:?}", datums);
892
893    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(&params.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/* REPLAY RHO RUNTIME */
1136
1137#[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    // Deserialization of parameters
1360    let params_slice = unsafe { std::slice::from_raw_parts(params_ptr, params_bytes_len) };
1361    let params = SourceToAdtParams::decode(params_slice).unwrap();
1362
1363    // Execution of transformation logic
1364    let result = match Compiler::source_to_adt_with_normalizer_env(
1365        &params.source,
1366        params.normalizer_env.into_iter().collect(),
1367    ) {
1368        Ok(par) => {
1369            // println!("\npar in source_to_adt: {:?}", par);
1370            par
1371        }
1372        Err(error) => {
1373            println!("source_to_adt rust side error {:?}", error);
1374            return std::ptr::null();
1375        }
1376    };
1377
1378    // Serialization of the result in `Par`
1379    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    // Add the length of the result at the beginning of the byte array
1384    let mut full_result = len_bytes;
1385    full_result.append(&mut result_bytes);
1386
1387    // Return a pointer to the serialized result
1388    Box::leak(full_result.into_boxed_slice()).as_ptr()
1389}