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