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