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