4fc325f08e0fb6fdf61417ddcf0942b965015a83
[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 serialized transaction, in (pointer, length) form.
90 ///
91 /// This type optionally owns its own memory, and thus the semantics around access change based on
92 /// the `data_is_owned` flag. If `data_is_owned` is set, you must call `Transaction_free` to free
93 /// the underlying buffer before the object goes out of scope. If `data_is_owned` is not set, any
94 /// access to the buffer after the scope in which the object was provided to you is invalid. eg,
95 /// access after you return from the call in which a `!data_is_owned` `Transaction` is provided to
96 /// you would be invalid.
97 ///
98 /// Note that, while it may change in the future, because transactions on the Rust side are stored
99 /// in a deserialized form, all `Transaction`s generated on the Rust side will have `data_is_owned`
100 /// set. Similarly, while it may change in the future, all `Transaction`s you pass to Rust may have
101 /// `data_is_owned` either set or unset at your discretion.
102 pub struct Transaction {
103         pub data: *const u8,
104         pub datalen: usize,
105         pub data_is_owned: bool,
106 }
107 impl Transaction {
108         pub(crate) fn into_bitcoin(&self) -> BitcoinTransaction {
109                 if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); }
110                 ::bitcoin::consensus::encode::deserialize(unsafe { std::slice::from_raw_parts(self.data, self.datalen) }).unwrap()
111         }
112         pub(crate) fn from_vec(v: Vec<u8>) -> Self {
113                 let datalen = v.len();
114                 let data = Box::into_raw(v.into_boxed_slice());
115                 Self {
116                         data: unsafe { (*data).as_mut_ptr() },
117                         datalen,
118                         data_is_owned: true,
119                 }
120         }
121 }
122 impl Drop for Transaction {
123         fn drop(&mut self) {
124                 if self.data_is_owned && self.datalen != 0 {
125                         let _ = CVecTempl { data: self.data as *mut u8, datalen: self.datalen };
126                 }
127         }
128 }
129 #[no_mangle]
130 pub extern "C" fn Transaction_free(_res: Transaction) { }
131
132 #[repr(C)]
133 #[derive(Clone)]
134 /// A transaction output including a scriptPubKey and value.
135 /// This type *does* own its own memory, so must be free'd appropriately.
136 pub struct TxOut {
137         pub script_pubkey: derived::CVec_u8Z,
138         pub value: u64,
139 }
140
141 impl TxOut {
142         pub(crate) fn into_rust(mut self) -> ::bitcoin::blockdata::transaction::TxOut {
143                 ::bitcoin::blockdata::transaction::TxOut {
144                         script_pubkey: self.script_pubkey.into_rust().into(),
145                         value: self.value,
146                 }
147         }
148         pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
149                 Self {
150                         script_pubkey: CVecTempl::from(txout.script_pubkey.into_bytes()),
151                         value: txout.value
152                 }
153         }
154 }
155 #[no_mangle]
156 pub extern "C" fn TxOut_free(_res: TxOut) { }
157
158 #[repr(C)]
159 pub struct u8slice {
160         pub data: *const u8,
161         pub datalen: usize
162 }
163 impl u8slice {
164         pub(crate) fn from_slice(s: &[u8]) -> Self {
165                 Self {
166                         data: s.as_ptr(),
167                         datalen: s.len(),
168                 }
169         }
170         pub(crate) fn to_slice(&self) -> &[u8] {
171                 if self.datalen == 0 { return &[]; }
172                 unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
173         }
174 }
175
176 #[repr(C)]
177 pub struct usizeslice {
178         pub data: *const usize,
179         pub datalen: usize
180 }
181 impl usizeslice {
182         pub(crate) fn from_slice(s: &[usize]) -> Self {
183                 Self {
184                         data: s.as_ptr(),
185                         datalen: s.len(),
186                 }
187         }
188         pub(crate) fn to_slice(&self) -> &[usize] {
189                 if self.datalen == 0 { return &[]; }
190                 unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
191         }
192 }
193
194 #[repr(C)]
195 #[derive(Copy, Clone)]
196 /// Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
197 /// look up the corresponding function in rust-lightning's docs.
198 pub struct ThirtyTwoBytes {
199         pub data: [u8; 32],
200 }
201 impl ThirtyTwoBytes {
202         pub(crate) fn null() -> Self {
203                 Self { data: [0; 32] }
204         }
205 }
206
207 #[repr(C)]
208 pub struct ThreeBytes { pub data: [u8; 3], }
209 #[derive(Clone)]
210 #[repr(C)]
211 pub struct FourBytes { pub data: [u8; 4], }
212 #[derive(Clone)]
213 #[repr(C)]
214 pub struct TenBytes { pub data: [u8; 10], }
215 #[derive(Clone)]
216 #[repr(C)]
217 pub struct SixteenBytes { pub data: [u8; 16], }
218
219 pub(crate) struct VecWriter(pub Vec<u8>);
220 impl lightning::util::ser::Writer for VecWriter {
221         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
222                 self.0.extend_from_slice(buf);
223                 Ok(())
224         }
225         fn size_hint(&mut self, size: usize) {
226                 self.0.reserve_exact(size);
227         }
228 }
229 pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
230         let mut out = VecWriter(Vec::new());
231         i.write(&mut out).unwrap();
232         CVecTempl::from(out.0)
233 }
234 pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
235         I::read(&mut s.to_slice())
236 }
237
238 #[repr(C)]
239 #[derive(Copy, Clone)]
240 /// A Rust str object, ie a reference to a UTF8-valid string.
241 /// This is *not* null-terminated so cannot be used directly as a C string!
242 pub struct Str {
243         pub chars: *const u8,
244         pub len: usize
245 }
246 impl Into<Str> for &'static str {
247         fn into(self) -> Str {
248                 Str { chars: self.as_ptr(), len: self.len() }
249         }
250 }
251 impl Into<&'static str> for Str {
252         fn into(self) -> &'static str {
253                 if self.len == 0 { return ""; }
254                 std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap()
255         }
256 }
257
258 // Note that the C++ headers memset(0) all the Templ types to avoid deallocation!
259 // Thus, they must gracefully handle being completely null in _free.
260
261 // TODO: Integer/bool primitives should avoid the pointer indirection for underlying types
262 // everywhere in the containers.
263
264 #[repr(C)]
265 pub union CResultPtr<O, E> {
266         pub result: *mut O,
267         pub err: *mut E,
268 }
269 #[repr(C)]
270 pub struct CResultTempl<O, E> {
271         pub contents: CResultPtr<O, E>,
272         pub result_ok: bool,
273 }
274 impl<O, E> CResultTempl<O, E> {
275         pub(crate) extern "C" fn ok(o: O) -> Self {
276                 CResultTempl {
277                         contents: CResultPtr {
278                                 result: Box::into_raw(Box::new(o)),
279                         },
280                         result_ok: true,
281                 }
282         }
283         pub(crate) extern "C" fn err(e: E) -> Self {
284                 CResultTempl {
285                         contents: CResultPtr {
286                                 err: Box::into_raw(Box::new(e)),
287                         },
288                         result_ok: false,
289                 }
290         }
291 }
292 pub extern "C" fn CResultTempl_free<O, E>(_res: CResultTempl<O, E>) { }
293 impl<O, E> Drop for CResultTempl<O, E> {
294         fn drop(&mut self) {
295                 if self.result_ok {
296                         if unsafe { !self.contents.result.is_null() } {
297                                 unsafe { Box::from_raw(self.contents.result) };
298                         }
299                 } else if unsafe { !self.contents.err.is_null() } {
300                         unsafe { Box::from_raw(self.contents.err) };
301                 }
302         }
303 }
304
305 #[repr(C)]
306 pub struct CVecTempl<T> {
307         pub data: *mut T,
308         pub datalen: usize
309 }
310 impl<T> CVecTempl<T> {
311         pub(crate) fn into_rust(&mut self) -> Vec<T> {
312                 if self.datalen == 0 { return Vec::new(); }
313                 let ret = unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }.into();
314                 self.data = std::ptr::null_mut();
315                 self.datalen = 0;
316                 ret
317         }
318         pub(crate) fn as_slice(&self) -> &[T] {
319                 unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) }
320         }
321 }
322 impl<T> From<Vec<T>> for CVecTempl<T> {
323         fn from(v: Vec<T>) -> Self {
324                 let datalen = v.len();
325                 let data = Box::into_raw(v.into_boxed_slice());
326                 CVecTempl { datalen, data: unsafe { (*data).as_mut_ptr() } }
327         }
328 }
329 pub extern "C" fn CVecTempl_free<T>(_res: CVecTempl<T>) { }
330 impl<T> Drop for CVecTempl<T> {
331         fn drop(&mut self) {
332                 if self.datalen == 0 { return; }
333                 unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) };
334         }
335 }
336 impl<T: Clone> Clone for CVecTempl<T> {
337         fn clone(&self) -> Self {
338                 let mut res = Vec::new();
339                 if self.datalen == 0 { return Self::from(res); }
340                 res.clone_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
341                 Self::from(res)
342         }
343 }
344
345 #[repr(C)]
346 pub struct C2TupleTempl<A, B> {
347         pub a: *mut A,
348         pub b: *mut B,
349 }
350 impl<A, B> From<(A, B)> for C2TupleTempl<A, B> {
351         fn from(tup: (A, B)) -> Self {
352                 Self {
353                         a: Box::into_raw(Box::new(tup.0)),
354                         b: Box::into_raw(Box::new(tup.1)),
355                 }
356         }
357 }
358 impl<A, B> C2TupleTempl<A, B> {
359         pub(crate) fn to_rust(mut self) -> (A, B) {
360                 let res = (unsafe { *Box::from_raw(self.a) }, unsafe { *Box::from_raw(self.b) });
361                 self.a = std::ptr::null_mut();
362                 self.b = std::ptr::null_mut();
363                 res
364         }
365 }
366 pub extern "C" fn C2TupleTempl_free<A, B>(_res: C2TupleTempl<A, B>) { }
367 impl<A, B> Drop for C2TupleTempl<A, B> {
368         fn drop(&mut self) {
369                 if !self.a.is_null() {
370                         unsafe { Box::from_raw(self.a) };
371                 }
372                 if !self.b.is_null() {
373                         unsafe { Box::from_raw(self.b) };
374                 }
375         }
376 }
377 impl <A: Clone, B: Clone> Clone for C2TupleTempl<A, B> {
378         fn clone(&self) -> Self {
379                 Self {
380                         a: Box::into_raw(Box::new(unsafe { &*self.a }.clone())),
381                         b: Box::into_raw(Box::new(unsafe { &*self.b }.clone()))
382                 }
383         }
384 }
385
386 #[repr(C)]
387 pub struct C3TupleTempl<A, B, C> {
388         pub a: *mut A,
389         pub b: *mut B,
390         pub c: *mut C,
391 }
392 impl<A, B, C> From<(A, B, C)> for C3TupleTempl<A, B, C> {
393         fn from(tup: (A, B, C)) -> Self {
394                 Self {
395                         a: Box::into_raw(Box::new(tup.0)),
396                         b: Box::into_raw(Box::new(tup.1)),
397                         c: Box::into_raw(Box::new(tup.2)),
398                 }
399         }
400 }
401 impl<A, B, C> C3TupleTempl<A, B, C> {
402         pub(crate) fn to_rust(mut self) -> (A, B, C) {
403                 let res = (unsafe { *Box::from_raw(self.a) }, unsafe { *Box::from_raw(self.b) }, unsafe { *Box::from_raw(self.c) });
404                 self.a = std::ptr::null_mut();
405                 self.b = std::ptr::null_mut();
406                 self.c = std::ptr::null_mut();
407                 res
408         }
409 }
410 pub extern "C" fn C3TupleTempl_free<A, B, C>(_res: C3TupleTempl<A, B, C>) { }
411 impl<A, B, C> Drop for C3TupleTempl<A, B, C> {
412         fn drop(&mut self) {
413                 if !self.a.is_null() {
414                         unsafe { Box::from_raw(self.a) };
415                 }
416                 if !self.b.is_null() {
417                         unsafe { Box::from_raw(self.b) };
418                 }
419                 if !self.c.is_null() {
420                         unsafe { Box::from_raw(self.c) };
421                 }
422         }
423 }
424
425 /// Utility to make it easy to set a pointer to null and get its original value in line.
426 pub(crate) trait TakePointer<T> {
427         fn take_ptr(&mut self) -> T;
428 }
429 impl<T> TakePointer<*const T> for *const T {
430         fn take_ptr(&mut self) -> *const T {
431                 let ret = *self;
432                 *self = std::ptr::null();
433                 ret
434         }
435 }
436 impl<T> TakePointer<*mut T> for *mut T {
437         fn take_ptr(&mut self) -> *mut T {
438                 let ret = *self;
439                 *self = std::ptr::null_mut();
440                 ret
441         }
442 }