simplicity_sys/
ffi.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! FFI Bindings
4//!
5//! This module contains bindings to the C library types and functions
6//! that are required to execute jets.
7//! It is split into several modules, each one corresponding to a `.h` file
8//! in the C library.
9//!
10//! All types are converted to CamelCase and prefixed with the letter C;
11//! function names are unchanged.
12
13#![allow(non_camel_case_types)]
14
15pub use core::ffi::c_void;
16
17pub type c_uchar = u8;
18pub type c_int = i32;
19pub type c_uint = u32;
20pub type c_size_t = usize;
21pub type c_uint_fast8_t = u8;
22#[cfg(any(target_os = "macos", target_os = "ios"))]
23pub type c_uint_fast16_t = u16;
24#[cfg(any(target_os = "windows", target_os = "android"))]
25pub type c_uint_fast16_t = u32;
26#[cfg(target_arch = "wasm32")]
27pub type c_uint_fast16_t = u16;
28#[cfg(not(any(
29    target_os = "macos",
30    target_os = "ios",
31    target_os = "windows",
32    target_os = "android",
33    target_arch = "wasm32"
34)))]
35pub type c_uint_fast16_t = usize;
36
37#[cfg(any(
38    target_os = "macos",
39    target_os = "ios",
40    target_os = "windows",
41    target_os = "android",
42    target_arch = "wasm32"
43))]
44pub type c_uint_fast32_t = u32;
45#[cfg(not(any(
46    target_os = "macos",
47    target_os = "ios",
48    target_os = "windows",
49    target_os = "android",
50    target_arch = "wasm32"
51)))]
52pub type c_uint_fast32_t = usize;
53#[cfg(target_arch = "wasm32")]
54pub type c_uint_fast64_t = u64;
55#[cfg(not(target_arch = "wasm32"))]
56pub type c_uint_fast64_t = usize;
57pub type c_uint_least32_t = u32;
58
59extern "C" {
60    pub static c_sizeof_uchar: c_size_t;
61    pub static c_alignof_uchar: c_size_t;
62    pub static c_sizeof_int: c_size_t;
63    pub static c_alignof_int: c_size_t;
64    pub static c_sizeof_uint: c_size_t;
65    pub static c_alignof_uint: c_size_t;
66    pub static c_sizeof_size_t: c_size_t;
67    pub static c_alignof_size_t: c_size_t;
68    pub static c_sizeof_uint_fast8_t: c_size_t;
69    pub static c_alignof_uint_fast8_t: c_size_t;
70    pub static c_sizeof_uint_fast16_t: c_size_t;
71    pub static c_alignof_uint_fast16_t: c_size_t;
72    pub static c_sizeof_uint_fast32_t: c_size_t;
73    pub static c_alignof_uint_fast32_t: c_size_t;
74    pub static c_sizeof_uint_fast64_t: c_size_t;
75    pub static c_alignof_uint_fast64_t: c_size_t;
76    pub static c_sizeof_uint_least32_t: c_size_t;
77    pub static c_alignof_uint_least32_t: c_size_t;
78    pub static c_sizeof_long_double: c_size_t;
79    pub static c_alignof_long_double: c_size_t;
80}
81
82pub type ubounded = c_uint_least32_t;
83/// Used with `evalTCOProgram` to enforce consensus limits.
84pub const BUDGET_MAX: ubounded = 4000050;
85/// The max value of UBOUNDED_MAX
86pub const UBOUNDED_MAX: ubounded = ubounded::MAX;
87
88extern "C" {
89    pub static c_sizeof_ubounded: c_size_t;
90    pub static c_alignof_ubounded: c_size_t;
91}
92
93pub mod bounded {
94    use super::ubounded;
95    extern "C" {
96        pub static c_overhead: ubounded;
97    }
98
99    /// constant Overhead of each jet
100    pub fn cost_overhead() -> ubounded {
101        unsafe { c_overhead }
102    }
103}
104
105pub type UWORD = c_uint_fast16_t;
106
107extern "C" {
108    pub static c_sizeof_UWORD: c_size_t;
109    pub static c_alignof_UWORD: c_size_t;
110}
111
112pub mod sha256 {
113    use super::*;
114    use hashes::sha256::Midstate;
115
116    /// The 256-bit array of a SHA-256 hash or midstate.
117    #[repr(C)]
118    #[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
119    pub struct CSha256Midstate {
120        pub s: [u32; 8],
121    }
122
123    impl From<CSha256Midstate> for Midstate {
124        fn from(c_midstate: CSha256Midstate) -> Midstate {
125            let mut inner = [0; 32];
126            for (idx, chunk) in c_midstate.s.iter().enumerate() {
127                inner[idx * 4..(idx + 1) * 4].copy_from_slice(&chunk.to_be_bytes());
128            }
129            Midstate(inner)
130        }
131    }
132
133    impl From<Midstate> for CSha256Midstate {
134        fn from(midstate: Midstate) -> CSha256Midstate {
135            let mut s = [0; 8];
136            for (idx, chunk) in midstate.0.chunks(4).enumerate() {
137                s[idx] = u32::from_be_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]);
138            }
139            CSha256Midstate { s }
140        }
141    }
142
143    extern "C" {
144        pub static c_sizeof_sha256_midstate: c_size_t;
145        pub static c_alignof_sha256_midstate: c_size_t;
146    }
147}
148
149#[cfg(test)]
150mod tests {
151    use super::*;
152    use std::mem::{align_of, size_of};
153
154    #[test]
155    #[rustfmt::skip]
156    fn test_sizes() {
157        unsafe {
158            assert_eq!(size_of::<c_uchar>(), c_sizeof_uchar);
159            assert_eq!(size_of::<c_int>(), c_sizeof_int);
160            assert_eq!(size_of::<c_uint>(), c_sizeof_uint);
161            assert_eq!(size_of::<c_size_t>(), c_sizeof_size_t);
162            assert_eq!(size_of::<c_uint_fast8_t>(), c_sizeof_uint_fast8_t);
163            assert_eq!(size_of::<c_uint_fast16_t>(), c_sizeof_uint_fast16_t);
164            assert_eq!(size_of::<c_uint_fast32_t>(), c_sizeof_uint_fast32_t);
165            assert_eq!(size_of::<c_uint_fast64_t>(), c_sizeof_uint_fast64_t);
166            assert_eq!(size_of::<c_uint_least32_t>(), c_sizeof_uint_least32_t);
167            assert_eq!(size_of::<ubounded>(), c_sizeof_ubounded);
168            assert_eq!(size_of::<UWORD>(), c_sizeof_UWORD);
169            assert_eq!(size_of::<sha256::CSha256Midstate>(), sha256::c_sizeof_sha256_midstate);
170        }
171    }
172
173    #[test]
174    #[rustfmt::skip]
175    fn test_aligns() {
176        unsafe {
177            assert_eq!(align_of::<c_uchar>(), c_alignof_uchar);
178            assert_eq!(align_of::<c_int>(), c_alignof_int);
179            assert_eq!(align_of::<c_uint>(), c_alignof_uint);
180            assert_eq!(align_of::<c_size_t>(), c_alignof_size_t);
181            assert_eq!(align_of::<c_uint_fast8_t>(), c_alignof_uint_fast8_t);
182            assert_eq!(align_of::<c_uint_fast16_t>(), c_alignof_uint_fast16_t);
183            assert_eq!(align_of::<c_uint_fast32_t>(), c_alignof_uint_fast32_t);
184            assert_eq!(align_of::<c_uint_fast64_t>(), c_alignof_uint_fast64_t);
185            assert_eq!(align_of::<c_uint_least32_t>(), c_alignof_uint_least32_t);
186            assert_eq!(align_of::<ubounded>(), c_alignof_ubounded);
187            assert_eq!(align_of::<UWORD>(), c_alignof_UWORD);
188            assert_eq!(align_of::<sha256::CSha256Midstate>(), sha256::c_alignof_sha256_midstate);
189        }
190    }
191}