be697d49639d2650b1e4dd9ee2ae57ad730f4128
[rust-lightning] / lightning-c-bindings / src / c_types / mod.rs
1 pub mod derived;
2
3 use bitcoin::Script as BitcoinScript;
4 use bitcoin::Transaction as BitcoinTransaction;
5 use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;
6 use bitcoin::secp256k1::key::SecretKey as SecpSecretKey;
7 use bitcoin::secp256k1::Signature as SecpSignature;
8 use bitcoin::secp256k1::Error as SecpError;
9
10 #[derive(Clone)]
11 #[repr(C)]
12 pub struct PublicKey {
13         pub compressed_form: [u8; 33],
14 }
15 impl PublicKey {
16         pub(crate) fn from_rust(pk: &SecpPublicKey) -> Self {
17                 Self {
18                         compressed_form: pk.serialize(),
19                 }
20         }
21         pub(crate) fn into_rust(&self) -> SecpPublicKey {
22                 SecpPublicKey::from_slice(&self.compressed_form).unwrap()
23         }
24         pub(crate) fn is_null(&self) -> bool { self.compressed_form[..] == [0; 33][..] }
25         pub(crate) fn null() -> Self { Self { compressed_form: [0; 33] } }
26 }
27
28 #[repr(C)]
29 pub struct SecretKey {
30         pub bytes: [u8; 32],
31 }
32 impl SecretKey {
33         // from_rust isn't implemented for a ref since we just return byte array refs directly
34         pub(crate) fn from_rust(sk: SecpSecretKey) -> Self {
35                 let mut bytes = [0; 32];
36                 bytes.copy_from_slice(&sk[..]);
37                 Self { bytes }
38         }
39         pub(crate) fn into_rust(&self) -> SecpSecretKey {
40                 SecpSecretKey::from_slice(&self.bytes).unwrap()
41         }
42 }
43
44 #[repr(C)]
45 pub struct Signature {
46         pub compact_form: [u8; 64],
47 }
48 impl Signature {
49         pub(crate) fn from_rust(pk: &SecpSignature) -> Self {
50                 Self {
51                         compact_form: pk.serialize_compact(),
52                 }
53         }
54         pub(crate) fn into_rust(&self) -> SecpSignature {
55                 SecpSignature::from_compact(&self.compact_form).unwrap()
56         }
57         pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
58         pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
59 }
60
61 #[repr(C)]
62 pub enum Secp256k1Error {
63         IncorrectSignature,
64         InvalidMessage,
65         InvalidPublicKey,
66         InvalidSignature,
67         InvalidSecretKey,
68         InvalidRecoveryId,
69         InvalidTweak,
70         NotEnoughMemory,
71         CallbackPanicked,
72 }
73 impl Secp256k1Error {
74         pub(crate) fn from_rust(err: SecpError) -> Self {
75                 match err {
76                         SecpError::IncorrectSignature => Secp256k1Error::IncorrectSignature,
77                         SecpError::InvalidMessage => Secp256k1Error::InvalidMessage,
78                         SecpError::InvalidPublicKey => Secp256k1Error::InvalidPublicKey,
79                         SecpError::InvalidSignature => Secp256k1Error::InvalidSignature,
80                         SecpError::InvalidSecretKey => Secp256k1Error::InvalidSecretKey,
81                         SecpError::InvalidRecoveryId => Secp256k1Error::InvalidRecoveryId,
82                         SecpError::InvalidTweak => Secp256k1Error::InvalidTweak,
83                         SecpError::NotEnoughMemory => Secp256k1Error::NotEnoughMemory,
84                 }
85         }
86 }
87
88 #[repr(C)]
89 /// A reference to a serialized transaction, in (pointer, length) form.
90 /// This type does *not* own its own memory, so access to it after, eg, the call in which it was
91 /// provided to you are invalid.
92 pub struct Transaction {
93         pub data: *const u8,
94         pub datalen: usize,
95 }
96 impl Transaction {
97         pub(crate) fn into_bitcoin(&self) -> BitcoinTransaction {
98                 if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); }
99                 ::bitcoin::consensus::encode::deserialize(unsafe { std::slice::from_raw_parts(self.data, self.datalen) }).unwrap()
100         }
101         pub(crate) fn from_slice(s: &[u8]) -> Self {
102                 Self {
103                         data: s.as_ptr(),
104                         datalen: s.len(),
105                 }
106         }
107 }
108
109 #[repr(C)]
110 #[derive(Clone)]
111 /// A transaction output including a scriptPubKey and value.
112 /// This type *does* own its own memory, so must be free'd appropriately.
113 pub struct TxOut {
114         pub script_pubkey: derived::CVec_u8Z,
115         pub value: u64,
116 }
117
118 impl TxOut {
119         pub(crate) fn into_rust(mut self) -> ::bitcoin::blockdata::transaction::TxOut {
120                 ::bitcoin::blockdata::transaction::TxOut {
121                         script_pubkey: self.script_pubkey.into_rust().into(),
122                         value: self.value,
123                 }
124         }
125         pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
126                 Self {
127                         script_pubkey: CVecTempl::from(txout.script_pubkey.into_bytes()),
128                         value: txout.value
129                 }
130         }
131 }
132 #[no_mangle]
133 pub extern "C" fn TxOut_free(_res: TxOut) { }
134
135 #[repr(C)]
136 pub struct u8slice {
137         pub data: *const u8,
138         pub datalen: usize
139 }
140 impl u8slice {
141         pub(crate) fn from_slice(s: &[u8]) -> Self {
142                 Self {
143                         data: s.as_ptr(),
144                         datalen: s.len(),
145                 }
146         }
147         pub(crate) fn to_slice(&self) -> &[u8] {
148                 if self.datalen == 0 { return &[]; }
149                 unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
150         }
151 }
152
153 #[repr(C)]
154 pub struct usizeslice {
155         pub data: *const usize,
156         pub datalen: usize
157 }
158 impl usizeslice {
159         pub(crate) fn from_slice(s: &[usize]) -> Self {
160                 Self {
161                         data: s.as_ptr(),
162                         datalen: s.len(),
163                 }
164         }
165         pub(crate) fn to_slice(&self) -> &[usize] {
166                 if self.datalen == 0 { return &[]; }
167                 unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
168         }
169 }
170
171 #[repr(C)]
172 #[derive(Copy, Clone)]
173 /// Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
174 /// look up the corresponding function in rust-lightning's docs.
175 pub struct ThirtyTwoBytes {
176         pub data: [u8; 32],
177 }
178 impl ThirtyTwoBytes {
179         pub(crate) fn null() -> Self {
180                 Self { data: [0; 32] }
181         }
182 }
183
184 #[repr(C)]
185 pub struct ThreeBytes { pub data: [u8; 3], }
186 #[derive(Clone)]
187 #[repr(C)]
188 pub struct FourBytes { pub data: [u8; 4], }
189 #[derive(Clone)]
190 #[repr(C)]
191 pub struct TenBytes { pub data: [u8; 10], }
192 #[derive(Clone)]
193 #[repr(C)]
194 pub struct SixteenBytes { pub data: [u8; 16], }
195
196 pub(crate) struct VecWriter(pub Vec<u8>);
197 impl lightning::util::ser::Writer for VecWriter {
198         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
199                 self.0.extend_from_slice(buf);
200                 Ok(())
201         }
202         fn size_hint(&mut self, size: usize) {
203                 self.0.reserve_exact(size);
204         }
205 }
206 pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
207         let mut out = VecWriter(Vec::new());
208         i.write(&mut out).unwrap();
209         CVecTempl::from(out.0)
210 }
211 pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
212         I::read(&mut s.to_slice())
213 }
214
215 #[repr(C)]
216 #[derive(Copy, Clone)]
217 /// A Rust str object, ie a reference to a UTF8-valid string.
218 /// This is *not* null-terminated so cannot be used directly as a C string!
219 pub struct Str {
220         pub chars: *const u8,
221         pub len: usize
222 }
223 impl Into<Str> for &'static str {
224         fn into(self) -> Str {
225                 Str { chars: self.as_ptr(), len: self.len() }
226         }
227 }
228 impl Into<&'static str> for Str {
229         fn into(self) -> &'static str {
230                 if self.len == 0 { return ""; }
231                 std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap()
232         }
233 }
234
235 // Note that the C++ headers memset(0) all the Templ types to avoid deallocation!
236 // Thus, they must gracefully handle being completely null in _free.
237
238 // TODO: Integer/bool primitives should avoid the pointer indirection for underlying types
239 // everywhere in the containers.
240
241 #[repr(C)]
242 pub union CResultPtr<O, E> {
243         pub result: *mut O,
244         pub err: *mut E,
245 }
246 #[repr(C)]
247 pub struct CResultTempl<O, E> {
248         pub contents: CResultPtr<O, E>,
249         pub result_ok: bool,
250 }
251 impl<O, E> CResultTempl<O, E> {
252         pub(crate) extern "C" fn ok(o: O) -> Self {
253                 CResultTempl {
254                         contents: CResultPtr {
255                                 result: Box::into_raw(Box::new(o)),
256                         },
257                         result_ok: true,
258                 }
259         }
260         pub(crate) extern "C" fn err(e: E) -> Self {
261                 CResultTempl {
262                         contents: CResultPtr {
263                                 err: Box::into_raw(Box::new(e)),
264                         },
265                         result_ok: false,
266                 }
267         }
268 }
269 pub extern "C" fn CResultTempl_free<O, E>(_res: CResultTempl<O, E>) { }
270 impl<O, E> Drop for CResultTempl<O, E> {
271         fn drop(&mut self) {
272                 if self.result_ok {
273                         if unsafe { !self.contents.result.is_null() } {
274                                 unsafe { Box::from_raw(self.contents.result) };
275                         }
276                 } else if unsafe { !self.contents.err.is_null() } {
277                         unsafe { Box::from_raw(self.contents.err) };
278                 }
279         }
280 }
281
282 #[repr(C)]
283 pub struct CVecTempl<T> {
284         pub data: *mut T,
285         pub datalen: usize
286 }
287 impl<T> CVecTempl<T> {
288         pub(crate) fn into_rust(&mut self) -> Vec<T> {
289                 if self.datalen == 0 { return Vec::new(); }
290                 let ret = unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }.into();
291                 self.data = std::ptr::null_mut();
292                 self.datalen = 0;
293                 ret
294         }
295         pub(crate) fn as_slice(&self) -> &[T] {
296                 unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) }
297         }
298 }
299 impl<T> From<Vec<T>> for CVecTempl<T> {
300         fn from(v: Vec<T>) -> Self {
301                 let datalen = v.len();
302                 let data = Box::into_raw(v.into_boxed_slice());
303                 CVecTempl { datalen, data: unsafe { (*data).as_mut_ptr() } }
304         }
305 }
306 pub extern "C" fn CVecTempl_free<T>(_res: CVecTempl<T>) { }
307 impl<T> Drop for CVecTempl<T> {
308         fn drop(&mut self) {
309                 if self.datalen == 0 { return; }
310                 unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) };
311         }
312 }
313 impl<T: Clone> Clone for CVecTempl<T> {
314         fn clone(&self) -> Self {
315                 let mut res = Vec::new();
316                 if self.datalen == 0 { return Self::from(res); }
317                 res.clone_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
318                 Self::from(res)
319         }
320 }
321
322 #[repr(C)]
323 pub struct C2TupleTempl<A, B> {
324         pub a: *mut A,
325         pub b: *mut B,
326 }
327 impl<A, B> From<(A, B)> for C2TupleTempl<A, B> {
328         fn from(tup: (A, B)) -> Self {
329                 Self {
330                         a: Box::into_raw(Box::new(tup.0)),
331                         b: Box::into_raw(Box::new(tup.1)),
332                 }
333         }
334 }
335 impl<A, B> C2TupleTempl<A, B> {
336         pub(crate) fn to_rust(mut self) -> (A, B) {
337                 let res = (unsafe { *Box::from_raw(self.a) }, unsafe { *Box::from_raw(self.b) });
338                 self.a = std::ptr::null_mut();
339                 self.b = std::ptr::null_mut();
340                 res
341         }
342 }
343 pub extern "C" fn C2TupleTempl_free<A, B>(_res: C2TupleTempl<A, B>) { }
344 impl<A, B> Drop for C2TupleTempl<A, B> {
345         fn drop(&mut self) {
346                 if !self.a.is_null() {
347                         unsafe { Box::from_raw(self.a) };
348                 }
349                 if !self.b.is_null() {
350                         unsafe { Box::from_raw(self.b) };
351                 }
352         }
353 }
354 impl <A: Clone, B: Clone> Clone for C2TupleTempl<A, B> {
355         fn clone(&self) -> Self {
356                 Self {
357                         a: Box::into_raw(Box::new(unsafe { &*self.a }.clone())),
358                         b: Box::into_raw(Box::new(unsafe { &*self.b }.clone()))
359                 }
360         }
361 }
362
363 #[repr(C)]
364 pub struct C3TupleTempl<A, B, C> {
365         pub a: *mut A,
366         pub b: *mut B,
367         pub c: *mut C,
368 }
369 impl<A, B, C> From<(A, B, C)> for C3TupleTempl<A, B, C> {
370         fn from(tup: (A, B, C)) -> Self {
371                 Self {
372                         a: Box::into_raw(Box::new(tup.0)),
373                         b: Box::into_raw(Box::new(tup.1)),
374                         c: Box::into_raw(Box::new(tup.2)),
375                 }
376         }
377 }
378 impl<A, B, C> C3TupleTempl<A, B, C> {
379         pub(crate) fn to_rust(mut self) -> (A, B, C) {
380                 let res = (unsafe { *Box::from_raw(self.a) }, unsafe { *Box::from_raw(self.b) }, unsafe { *Box::from_raw(self.c) });
381                 self.a = std::ptr::null_mut();
382                 self.b = std::ptr::null_mut();
383                 self.c = std::ptr::null_mut();
384                 res
385         }
386 }
387 pub extern "C" fn C3TupleTempl_free<A, B, C>(_res: C3TupleTempl<A, B, C>) { }
388 impl<A, B, C> Drop for C3TupleTempl<A, B, C> {
389         fn drop(&mut self) {
390                 if !self.a.is_null() {
391                         unsafe { Box::from_raw(self.a) };
392                 }
393                 if !self.b.is_null() {
394                         unsafe { Box::from_raw(self.b) };
395                 }
396                 if !self.c.is_null() {
397                         unsafe { Box::from_raw(self.c) };
398                 }
399         }
400 }
401
402 /// Utility to make it easy to set a pointer to null and get its original value in line.
403 pub(crate) trait TakePointer<T> {
404         fn take_ptr(&mut self) -> T;
405 }
406 impl<T> TakePointer<*const T> for *const T {
407         fn take_ptr(&mut self) -> *const T {
408                 let ret = *self;
409                 *self = std::ptr::null();
410                 ret
411         }
412 }
413 impl<T> TakePointer<*mut T> for *mut T {
414         fn take_ptr(&mut self) -> *mut T {
415                 let ret = *self;
416                 *self = std::ptr::null_mut();
417                 ret
418         }
419 }