Merge pull request #17 from TheBlueMatt/2021-04-upstream-confirm
[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_bitcoin(btc: &BitcoinTransaction) -> Self {
191                 let vec = ::bitcoin::consensus::encode::serialize(btc);
192                 let datalen = vec.len();
193                 let data = Box::into_raw(vec.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 }