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(all(
23    any(target_arch = "wasm32", target_arch = "aarch64"),
24    not(target_os = "windows")
25))]
26pub type c_uint_fast16_t = u16;
27#[cfg(target_os = "windows")]
28pub type c_uint_fast16_t = u32;
29#[cfg(not(any(target_arch = "wasm32", target_arch = "aarch64", target_os = "windows")))]
30pub type c_uint_fast16_t = usize;
31#[cfg(any(target_arch = "wasm32", target_arch = "aarch64", target_os = "windows"))]
32pub type c_uint_fast32_t = u32;
33#[cfg(not(any(target_arch = "wasm32", target_arch = "aarch64", target_os = "windows")))]
34pub type c_uint_fast32_t = usize;
35#[cfg(target_arch = "wasm32")]
36pub type c_uint_fast64_t = u64;
37#[cfg(not(target_arch = "wasm32"))]
38pub type c_uint_fast64_t = usize;
39pub type c_uint_least32_t = u32;
40
41extern "C" {
42    pub static c_sizeof_uchar: c_size_t;
43    pub static c_alignof_uchar: c_size_t;
44    pub static c_sizeof_int: c_size_t;
45    pub static c_alignof_int: c_size_t;
46    pub static c_sizeof_uint: c_size_t;
47    pub static c_alignof_uint: c_size_t;
48    pub static c_sizeof_size_t: c_size_t;
49    pub static c_alignof_size_t: c_size_t;
50    pub static c_sizeof_uint_fast8_t: c_size_t;
51    pub static c_alignof_uint_fast8_t: c_size_t;
52    pub static c_sizeof_uint_fast16_t: c_size_t;
53    pub static c_alignof_uint_fast16_t: c_size_t;
54    pub static c_sizeof_uint_fast32_t: c_size_t;
55    pub static c_alignof_uint_fast32_t: c_size_t;
56    pub static c_sizeof_uint_fast64_t: c_size_t;
57    pub static c_alignof_uint_fast64_t: c_size_t;
58    pub static c_sizeof_uint_least32_t: c_size_t;
59    pub static c_alignof_uint_least32_t: c_size_t;
60    pub static c_sizeof_long_double: c_size_t;
61    pub static c_alignof_long_double: c_size_t;
62}
63
64pub type ubounded = c_uint_least32_t;
65/// Used with `evalTCOProgram` to enforce consensus limits.
66pub const BUDGET_MAX: ubounded = 4000050;
67/// The max value of UBOUNDED_MAX
68pub const UBOUNDED_MAX: ubounded = ubounded::MAX;
69
70extern "C" {
71    pub static c_sizeof_ubounded: c_size_t;
72    pub static c_alignof_ubounded: c_size_t;
73}
74
75pub mod bounded {
76    use super::ubounded;
77    extern "C" {
78        pub static c_overhead: ubounded;
79    }
80
81    /// constant Overhead of each jet
82    pub fn cost_overhead() -> ubounded {
83        unsafe { c_overhead }
84    }
85}
86
87pub type UWORD = c_uint_fast16_t;
88
89extern "C" {
90    pub static c_sizeof_UWORD: c_size_t;
91    pub static c_alignof_UWORD: c_size_t;
92}
93
94pub mod sha256 {
95    use super::*;
96    use hashes::sha256::Midstate;
97
98    /// The 256-bit array of a SHA-256 hash or midstate.
99    #[repr(C)]
100    #[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
101    pub struct CSha256Midstate {
102        pub s: [u32; 8],
103    }
104
105    impl From<CSha256Midstate> for Midstate {
106        fn from(c_midstate: CSha256Midstate) -> Midstate {
107            let mut inner = [0; 32];
108            for (idx, chunk) in c_midstate.s.iter().enumerate() {
109                inner[idx * 4..(idx + 1) * 4].copy_from_slice(&chunk.to_be_bytes());
110            }
111            Midstate(inner)
112        }
113    }
114
115    impl From<Midstate> for CSha256Midstate {
116        fn from(midstate: Midstate) -> CSha256Midstate {
117            let mut s = [0; 8];
118            for (idx, chunk) in midstate.0.chunks(4).enumerate() {
119                s[idx] = u32::from_be_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]);
120            }
121            CSha256Midstate { s }
122        }
123    }
124
125    extern "C" {
126        pub static c_sizeof_sha256_midstate: c_size_t;
127        pub static c_alignof_sha256_midstate: c_size_t;
128    }
129}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134    use std::mem::{align_of, size_of};
135
136    #[test]
137    #[rustfmt::skip]
138    fn test_sizes() {
139        unsafe {
140            assert_eq!(size_of::<c_uchar>(), c_sizeof_uchar);
141            assert_eq!(size_of::<c_int>(), c_sizeof_int);
142            assert_eq!(size_of::<c_uint>(), c_sizeof_uint);
143            assert_eq!(size_of::<c_size_t>(), c_sizeof_size_t);
144            assert_eq!(size_of::<c_uint_fast8_t>(), c_sizeof_uint_fast8_t);
145            assert_eq!(size_of::<c_uint_fast16_t>(), c_sizeof_uint_fast16_t);
146            assert_eq!(size_of::<c_uint_fast32_t>(), c_sizeof_uint_fast32_t);
147            assert_eq!(size_of::<c_uint_fast64_t>(), c_sizeof_uint_fast64_t);
148            assert_eq!(size_of::<c_uint_least32_t>(), c_sizeof_uint_least32_t);
149            assert_eq!(size_of::<ubounded>(), c_sizeof_ubounded);
150            assert_eq!(size_of::<UWORD>(), c_sizeof_UWORD);
151            assert_eq!(size_of::<sha256::CSha256Midstate>(), sha256::c_sizeof_sha256_midstate);
152        }
153    }
154
155    #[test]
156    #[rustfmt::skip]
157    fn test_aligns() {
158        unsafe {
159            assert_eq!(align_of::<c_uchar>(), c_alignof_uchar);
160            assert_eq!(align_of::<c_int>(), c_alignof_int);
161            assert_eq!(align_of::<c_uint>(), c_alignof_uint);
162            assert_eq!(align_of::<c_size_t>(), c_alignof_size_t);
163            assert_eq!(align_of::<c_uint_fast8_t>(), c_alignof_uint_fast8_t);
164            assert_eq!(align_of::<c_uint_fast16_t>(), c_alignof_uint_fast16_t);
165            assert_eq!(align_of::<c_uint_fast32_t>(), c_alignof_uint_fast32_t);
166            assert_eq!(align_of::<c_uint_fast64_t>(), c_alignof_uint_fast64_t);
167            assert_eq!(align_of::<c_uint_least32_t>(), c_alignof_uint_least32_t);
168            assert_eq!(align_of::<ubounded>(), c_alignof_ubounded);
169            assert_eq!(align_of::<UWORD>(), c_alignof_UWORD);
170            assert_eq!(align_of::<sha256::CSha256Midstate>(), sha256::c_alignof_sha256_midstate);
171        }
172    }
173}