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