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