simplicity_sys/c_jets/c_env/
elements.rs

1// SPDX-License-Identifier: CC0-1.0
2
3use hashes::{sha256, Hash};
4
5use crate::ffi::sha256::CSha256Midstate;
6use crate::ffi::{c_size_t, c_uchar, c_uint, c_uint_fast32_t};
7
8#[derive(Debug)]
9#[repr(C)]
10pub struct CRawBuffer {
11    pub ptr: *const c_uchar,
12    pub len: u32,
13}
14
15#[derive(Debug)]
16#[repr(C)]
17pub struct CRawOutput<'raw> {
18    pub asset: Option<&'raw [c_uchar; 33]>,
19    pub value: *const c_uchar,
20    pub nonce: Option<&'raw [c_uchar; 33]>,
21    pub script_pubkey: CRawBuffer,
22    pub surjection_proof: CRawBuffer,
23    pub range_proof: CRawBuffer,
24}
25
26#[repr(C)]
27pub struct CRawInputIssuance<'raw> {
28    pub blinding_nonce: Option<&'raw [c_uchar; 32]>,
29    pub asset_entropy: Option<&'raw [c_uchar; 32]>,
30    pub amount: *const c_uchar,
31    pub inflation_keys: *const c_uchar,
32    pub amount_range_proof: CRawBuffer,
33    pub inflation_keys_range_proof: CRawBuffer,
34}
35
36impl<'raw> CRawInputIssuance<'raw> {
37    /// Constructs a raw input issuance structure corresponding to "no issuance".
38    pub fn no_issuance() -> Self {
39        Self {
40            blinding_nonce: None,
41            asset_entropy: None,
42            amount: core::ptr::null(),
43            inflation_keys: core::ptr::null(),
44            amount_range_proof: CRawBuffer::new(&[]),
45            inflation_keys_range_proof: CRawBuffer::new(&[]),
46        }
47    }
48}
49
50#[repr(C)]
51pub struct CRawInputTxo<'raw> {
52    pub asset: Option<&'raw [c_uchar; 33]>,
53    pub value: *const c_uchar,
54    pub script_pubkey: CRawBuffer,
55}
56
57#[repr(C)]
58pub struct CRawInput<'raw> {
59    pub annex: *const CRawBuffer,
60    pub prev_txid: &'raw [c_uchar; 32],
61    pub pegin: Option<&'raw [c_uchar; 32]>,
62    pub issuance: CRawInputIssuance<'raw>,
63    pub txo: CRawInputTxo<'raw>,
64    pub script_sig: CRawBuffer,
65    pub prev_txout_index: u32,
66    pub sequence: u32,
67}
68
69#[derive(Debug)]
70#[repr(C)]
71pub struct CRawTransaction<'raw> {
72    pub txid: &'raw [c_uchar; 32],
73    pub inputs: *const CRawInput<'raw>,
74    pub outputs: *const CRawOutput<'raw>,
75    pub n_inputs: u32,
76    pub n_outputs: u32,
77    pub version: u32,
78    pub locktime: u32,
79}
80
81#[derive(Debug)]
82#[repr(C)]
83pub struct CRawTapEnv {
84    pub control_block: *const c_uchar,
85    pub script_cmr: *const c_uchar,
86    pub branch_len: u8,
87}
88
89#[repr(C)]
90pub struct CTransaction {
91    _data: (),
92}
93
94#[derive(Debug)]
95#[repr(C)]
96pub struct CTxEnv {
97    tx: *const CTransaction,
98    taproot: *const CTapEnv,
99    genesis_hash: CSha256Midstate,
100    sighash_all: CSha256Midstate,
101    ix: c_uint_fast32_t,
102}
103
104#[repr(C)]
105pub struct CTapEnv {
106    _data: (),
107}
108
109extern "C" {
110    #[link_name = "rustsimplicity_0_6_c_sizeof_rawElementsBuffer"]
111    pub static c_sizeof_rawBuffer: c_size_t;
112    #[link_name = "rustsimplicity_0_6_c_sizeof_rawElementsOutput"]
113    pub static c_sizeof_rawOutput: c_size_t;
114    #[link_name = "rustsimplicity_0_6_c_sizeof_rawElementsInput"]
115    pub static c_sizeof_rawInput: c_size_t;
116    #[link_name = "rustsimplicity_0_6_c_sizeof_rawElementsTransaction"]
117    pub static c_sizeof_rawTransaction: c_size_t;
118    #[link_name = "rustsimplicity_0_6_c_sizeof_rawElementsTapEnv"]
119    pub static c_sizeof_rawTapEnv: c_size_t;
120    #[link_name = "rustsimplicity_0_6_c_sizeof_txEnv"]
121    pub static c_sizeof_txEnv: c_size_t;
122
123    #[link_name = "rustsimplicity_0_6_c_alignof_rawElementsBuffer"]
124    pub static c_alignof_rawBuffer: c_size_t;
125    #[link_name = "rustsimplicity_0_6_c_alignof_rawElementsOutput"]
126    pub static c_alignof_rawOutput: c_size_t;
127    #[link_name = "rustsimplicity_0_6_c_alignof_rawElementsInput"]
128    pub static c_alignof_rawInput: c_size_t;
129    #[link_name = "rustsimplicity_0_6_c_alignof_rawElementsTransaction"]
130    pub static c_alignof_rawTransaction: c_size_t;
131    #[link_name = "rustsimplicity_0_6_c_alignof_rawElementsTapEnv"]
132    pub static c_alignof_rawTapEnv: c_size_t;
133    #[link_name = "rustsimplicity_0_6_c_alignof_txEnv"]
134    pub static c_alignof_txEnv: c_size_t;
135
136    #[link_name = "rustsimplicity_0_6_c_set_txEnv"]
137    pub fn c_set_txEnv(
138        result: *mut CTxEnv,
139        tx: *const CTransaction,
140        taproot: *const CTapEnv,
141        genesisHash: *const c_uchar,
142        ix: c_uint,
143    );
144    #[link_name = "rustsimplicity_0_6_elements_mallocTapEnv"]
145    pub fn simplicity_mallocTapEnv(rawEnv: *const CRawTapEnv) -> *mut CTapEnv;
146    #[link_name = "rustsimplicity_0_6_elements_mallocTransaction"]
147    pub fn simplicity_mallocTransaction(rawTx: *const CRawTransaction) -> *mut CTransaction;
148}
149impl CTxEnv {
150    pub fn sighash_all(&self) -> sha256::Hash {
151        let midstate: sha256::Midstate = self.sighash_all.into();
152        sha256::Hash::from_byte_array(midstate.to_byte_array())
153    }
154}
155
156// Pointer must be manually free after dropping
157impl Drop for CTxEnv {
158    fn drop(&mut self) {
159        unsafe {
160            crate::alloc::rust_0_6_free(self.tx as *mut u8);
161            crate::alloc::rust_0_6_free(self.taproot as *mut u8);
162        }
163    }
164}
165
166impl CRawBuffer {
167    pub fn new(buf: &[c_uchar]) -> Self {
168        Self {
169            ptr: buf.as_ptr(),
170            len: buf.len().try_into().expect("sane buffer lengths"),
171        }
172    }
173}
174
175#[cfg(test)]
176mod tests {
177    use core::mem::{align_of, size_of};
178
179    use crate::c_jets::frame_ffi::{c_alignof_frameItem, c_sizeof_frameItem, CFrameItem};
180
181    use super::*;
182
183    #[test]
184    fn test_sizes() {
185        unsafe {
186            assert_eq!(size_of::<CFrameItem>(), c_sizeof_frameItem);
187            assert_eq!(size_of::<CRawBuffer>(), c_sizeof_rawBuffer);
188            assert_eq!(size_of::<CRawInput>(), c_sizeof_rawInput);
189            assert_eq!(size_of::<CRawOutput>(), c_sizeof_rawOutput);
190            assert_eq!(size_of::<CRawTransaction>(), c_sizeof_rawTransaction);
191            assert_eq!(size_of::<CRawTapEnv>(), c_sizeof_rawTapEnv);
192            assert_eq!(size_of::<CTxEnv>(), c_sizeof_txEnv);
193        }
194    }
195
196    #[test]
197    fn test_aligns() {
198        unsafe {
199            assert_eq!(align_of::<CFrameItem>(), c_alignof_frameItem);
200            assert_eq!(align_of::<CRawBuffer>(), c_alignof_rawBuffer);
201            assert_eq!(align_of::<CRawInput>(), c_alignof_rawInput);
202            assert_eq!(align_of::<CRawOutput>(), c_alignof_rawOutput);
203            assert_eq!(align_of::<CRawTransaction>(), c_alignof_rawTransaction);
204            assert_eq!(align_of::<CRawTapEnv>(), c_alignof_rawTapEnv);
205            assert_eq!(align_of::<CTxEnv>(), c_alignof_txEnv);
206        }
207    }
208}