1use neo_types::*;
9use std::slice::Iter;
10
11mod host_notifications;
12mod storage;
13mod syscalls;
14mod wrapper;
15
16pub use host_notifications::{
17 record as record_notification, reset as reset_recorded_notifications,
18 take as take_recorded_notifications, RecordedNotification,
19};
20pub use syscalls::SYSCALLS;
21pub use wrapper::{neovm_syscall, NeoVMSyscall};
22
23pub struct NeoVMSyscallRegistry {
25 syscalls: &'static [NeoVMSyscallInfo],
26}
27
28impl NeoVMSyscallRegistry {
29 pub const fn new(syscalls: &'static [NeoVMSyscallInfo]) -> Self {
30 Self { syscalls }
31 }
32
33 pub fn get_syscall(&self, name: &str) -> Option<&NeoVMSyscallInfo> {
34 self.syscalls.iter().find(|s| s.name == name)
35 }
36
37 pub fn get_syscall_by_hash(&self, hash: u32) -> Option<&NeoVMSyscallInfo> {
38 self.syscalls.iter().find(|s| s.hash == hash)
39 }
40
41 pub fn has_syscall(&self, name: &str) -> bool {
42 self.get_syscall(name).is_some()
43 }
44
45 pub fn get_instance() -> Self {
46 Self::new(SYSCALLS)
47 }
48
49 pub fn iter(&self) -> Iter<'static, NeoVMSyscallInfo> {
50 self.syscalls.iter()
51 }
52
53 pub fn names(&self) -> impl Iterator<Item = &'static str> {
54 self.syscalls.iter().map(|info| info.name)
55 }
56}
57
58#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct NeoVMSyscallInfo {
61 pub name: &'static str,
62 pub hash: u32,
63 pub parameters: &'static [&'static str],
64 pub return_type: &'static str,
65 pub gas_cost: u32,
66 pub description: &'static str,
67}
68
69pub struct NeoVMSyscallLowering;
71
72impl Default for NeoVMSyscallLowering {
73 fn default() -> Self {
74 Self::new()
75 }
76}
77
78impl NeoVMSyscallLowering {
79 pub fn new() -> Self {
80 Self
81 }
82
83 pub fn lower_syscall(&self, name: &str) -> NeoResult<u32> {
84 let registry = NeoVMSyscallRegistry::get_instance();
85 if let Some(syscall) = registry.get_syscall(name) {
86 Ok(syscall.hash)
87 } else {
88 Err(NeoError::new(&format!("Unknown syscall: {}", name)))
89 }
90 }
91
92 pub fn can_lower(&self, name: &str) -> bool {
93 let registry = NeoVMSyscallRegistry::get_instance();
94 registry.has_syscall(name)
95 }
96}
97
98pub static SYSCALL_REGISTRY: NeoVMSyscallRegistry = NeoVMSyscallRegistry::new(SYSCALLS);