Initial checkin with no changes from current RL git head
[ldk-c-bindings] / 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 #[derive(Clone)]
49 pub struct Signature {
50         pub compact_form: [u8; 64],
51 }
52 impl Signature {
53         pub(crate) fn from_rust(pk: &SecpSignature) -> Self {
54                 Self {
55                         compact_form: pk.serialize_compact(),
56                 }
57         }
58         pub(crate) fn into_rust(&self) -> SecpSignature {
59                 SecpSignature::from_compact(&self.compact_form).unwrap()
60         }
61         // The following are used for Option<Signature> which we support, but don't use anymore
62         #[allow(unused)] pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
63         #[allow(unused)] pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
64 }
65
66 #[repr(C)]
67 pub enum Secp256k1Error {
68         IncorrectSignature,
69         InvalidMessage,
70         InvalidPublicKey,
71         InvalidSignature,
72         InvalidSecretKey,
73         InvalidRecoveryId,
74         InvalidTweak,
75         TweakCheckFailed,
76         NotEnoughMemory,
77 }
78 impl Secp256k1Error {
79         pub(crate) fn from_rust(err: SecpError) -> Self {
80                 match err {
81                         SecpError::IncorrectSignature => Secp256k1Error::IncorrectSignature,
82                         SecpError::InvalidMessage => Secp256k1Error::InvalidMessage,
83                         SecpError::InvalidPublicKey => Secp256k1Error::InvalidPublicKey,
84                         SecpError::InvalidSignature => Secp256k1Error::InvalidSignature,
85                         SecpError::InvalidSecretKey => Secp256k1Error::InvalidSecretKey,
86                         SecpError::InvalidRecoveryId => Secp256k1Error::InvalidRecoveryId,
87                         SecpError::InvalidTweak => Secp256k1Error::InvalidTweak,
88                         SecpError::TweakCheckFailed => Secp256k1Error::TweakCheckFailed,
89                         SecpError::NotEnoughMemory => Secp256k1Error::NotEnoughMemory,
90                 }
91         }
92 }
93
94 #[repr(C)]
95 /// A serialized transaction, in (pointer, length) form.
96 ///
97 /// This type optionally owns its own memory, and thus the semantics around access change based on
98 /// the `data_is_owned` flag. If `data_is_owned` is set, you must call `Transaction_free` to free
99 /// the underlying buffer before the object goes out of scope. If `data_is_owned` is not set, any
100 /// access to the buffer after the scope in which the object was provided to you is invalid. eg,
101 /// access after you return from the call in which a `!data_is_owned` `Transaction` is provided to
102 /// you would be invalid.
103 ///
104 /// Note that, while it may change in the future, because transactions on the Rust side are stored
105 /// in a deserialized form, all `Transaction`s generated on the Rust side will have `data_is_owned`
106 /// set. Similarly, while it may change in the future, all `Transaction`s you pass to Rust may have
107 /// `data_is_owned` either set or unset at your discretion.
108 pub struct Transaction {
109         /// This is non-const for your convenience, an object passed to Rust is never written to.
110         pub data: *mut u8,
111         pub datalen: usize,
112         pub data_is_owned: bool,
113 }
114 impl Transaction {
115         pub(crate) fn into_bitcoin(&self) -> BitcoinTransaction {
116                 if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); }
117                 ::bitcoin::consensus::encode::deserialize(unsafe { std::slice::from_raw_parts(self.data, self.datalen) }).unwrap()
118         }
119         pub(crate) fn from_vec(v: Vec<u8>) -> Self {
120                 let datalen = v.len();
121                 let data = Box::into_raw(v.into_boxed_slice());
122                 Self {
123                         data: unsafe { (*data).as_mut_ptr() },
124                         datalen,
125                         data_is_owned: true,
126                 }
127         }
128 }
129 impl Drop for Transaction {
130         fn drop(&mut self) {
131                 if self.data_is_owned && self.datalen != 0 {
132                         let _ = derived::CVec_u8Z { data: self.data as *mut u8, datalen: self.datalen };
133                 }
134         }
135 }
136 #[no_mangle]
137 pub extern "C" fn Transaction_free(_res: Transaction) { }
138
139 pub(crate) fn bitcoin_to_C_outpoint(outpoint: ::bitcoin::blockdata::transaction::OutPoint) -> crate::chain::transaction::OutPoint {
140         crate::chain::transaction::OutPoint_new(ThirtyTwoBytes { data: outpoint.txid.into_inner() }, outpoint.vout.try_into().unwrap())
141 }
142
143 #[repr(C)]
144 #[derive(Clone)]
145 /// A transaction output including a scriptPubKey and value.
146 /// This type *does* own its own memory, so must be free'd appropriately.
147 pub struct TxOut {
148         pub script_pubkey: derived::CVec_u8Z,
149         pub value: u64,
150 }
151
152 impl TxOut {
153         pub(crate) fn into_rust(mut self) -> ::bitcoin::blockdata::transaction::TxOut {
154                 ::bitcoin::blockdata::transaction::TxOut {
155                         script_pubkey: self.script_pubkey.into_rust().into(),
156                         value: self.value,
157                 }
158         }
159         pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
160                 Self {
161                         script_pubkey: derived::CVec_u8Z::from(txout.script_pubkey.into_bytes()),
162                         value: txout.value
163                 }
164         }
165 }
166 #[no_mangle]
167 pub extern "C" fn TxOut_free(_res: TxOut) { }
168 #[no_mangle]
169 pub extern "C" fn TxOut_clone(orig: &TxOut) -> TxOut { orig.clone() }
170
171 #[repr(C)]
172 pub struct u8slice {
173         pub data: *const u8,
174         pub datalen: usize
175 }
176 impl u8slice {
177         pub(crate) fn from_slice(s: &[u8]) -> Self {
178                 Self {
179                         data: s.as_ptr(),
180                         datalen: s.len(),
181                 }
182         }
183         pub(crate) fn to_slice(&self) -> &[u8] {
184                 if self.datalen == 0 { return &[]; }
185                 unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
186         }
187 }
188
189 #[repr(C)]
190 #[derive(Copy, Clone)]
191 /// Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
192 /// look up the corresponding function in rust-lightning's docs.
193 pub struct ThirtyTwoBytes {
194         pub data: [u8; 32],
195 }
196 impl ThirtyTwoBytes {
197         pub(crate) fn null() -> Self {
198                 Self { data: [0; 32] }
199         }
200 }
201
202 #[repr(C)]
203 pub struct ThreeBytes { pub data: [u8; 3], }
204 #[derive(Clone)]
205 #[repr(C)]
206 pub struct FourBytes { pub data: [u8; 4], }
207 #[derive(Clone)]
208 #[repr(C)]
209 pub struct TenBytes { pub data: [u8; 10], }
210 #[derive(Clone)]
211 #[repr(C)]
212 pub struct SixteenBytes { pub data: [u8; 16], }
213
214 pub(crate) struct VecWriter(pub Vec<u8>);
215 impl lightning::util::ser::Writer for VecWriter {
216         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
217                 self.0.extend_from_slice(buf);
218                 Ok(())
219         }
220         fn size_hint(&mut self, size: usize) {
221                 self.0.reserve_exact(size);
222         }
223 }
224 pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
225         let mut out = VecWriter(Vec::new());
226         i.write(&mut out).unwrap();
227         derived::CVec_u8Z::from(out.0)
228 }
229 pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
230         I::read(&mut s.to_slice())
231 }
232 pub(crate) fn deserialize_obj_arg<A, I: lightning::util::ser::ReadableArgs<A>>(s: u8slice, args: A) -> Result<I, lightning::ln::msgs::DecodeError> {
233         I::read(&mut s.to_slice(), args)
234 }
235
236 #[repr(C)]
237 #[derive(Copy, Clone)]
238 /// A Rust str object, ie a reference to a UTF8-valid string.
239 /// This is *not* null-terminated so cannot be used directly as a C string!
240 pub struct Str {
241         pub chars: *const u8,
242         pub len: usize
243 }
244 impl Into<Str> for &'static str {
245         fn into(self) -> Str {
246                 Str { chars: self.as_ptr(), len: self.len() }
247         }
248 }
249 impl Into<&'static str> for Str {
250         fn into(self) -> &'static str {
251                 if self.len == 0 { return ""; }
252                 std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap()
253         }
254 }
255
256 // Note that the C++ headers memset(0) all the Templ types to avoid deallocation!
257 // Thus, they must gracefully handle being completely null in _free.
258
259 // TODO: Integer/bool primitives should avoid the pointer indirection for underlying types
260 // everywhere in the containers.
261
262 #[repr(C)]
263 pub(crate) union CResultPtr<O, E> {
264         pub(crate) result: *mut O,
265         pub(crate) err: *mut E,
266 }
267 #[repr(C)]
268 pub(crate) struct CResultTempl<O, E> {
269         pub(crate) contents: CResultPtr<O, E>,
270         pub(crate) result_ok: bool,
271 }
272 impl<O, E> CResultTempl<O, E> {
273         pub(crate) extern "C" fn ok(o: O) -> Self {
274                 CResultTempl {
275                         contents: CResultPtr {
276                                 result: Box::into_raw(Box::new(o)),
277                         },
278                         result_ok: true,
279                 }
280         }
281         pub(crate) extern "C" fn err(e: E) -> Self {
282                 CResultTempl {
283                         contents: CResultPtr {
284                                 err: Box::into_raw(Box::new(e)),
285                         },
286                         result_ok: false,
287                 }
288         }
289 }
290 impl<O, E> Drop for CResultTempl<O, E> {
291         fn drop(&mut self) {
292                 if self.result_ok {
293                         if unsafe { !self.contents.result.is_null() } {
294                                 unsafe { Box::from_raw(self.contents.result) };
295                         }
296                 } else if unsafe { !self.contents.err.is_null() } {
297                         unsafe { Box::from_raw(self.contents.err) };
298                 }
299         }
300 }
301
302 /// Utility to make it easy to set a pointer to null and get its original value in line.
303 pub(crate) trait TakePointer<T> {
304         fn take_ptr(&mut self) -> T;
305 }
306 impl<T> TakePointer<*const T> for *const T {
307         fn take_ptr(&mut self) -> *const T {
308                 let ret = *self;
309                 *self = std::ptr::null();
310                 ret
311         }
312 }
313 impl<T> TakePointer<*mut T> for *mut T {
314         fn take_ptr(&mut self) -> *mut T {
315                 let ret = *self;
316                 *self = std::ptr::null_mut();
317                 ret
318         }
319 }