Merge pull request #767 from TheBlueMatt/2020-12-chansigner-read-bindings
[rust-lightning] / lightning-c-bindings / src / c_types / mod.rs
index 813e401b8e7e2b5f567b8791117c815c02aa0d61..20c49a6d92b30f0c96ad2ac6e394fbfbbcfa2c31 100644 (file)
@@ -2,11 +2,14 @@ pub mod derived;
 
 use bitcoin::Script as BitcoinScript;
 use bitcoin::Transaction as BitcoinTransaction;
+use bitcoin::hashes::Hash;
 use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;
 use bitcoin::secp256k1::key::SecretKey as SecpSecretKey;
 use bitcoin::secp256k1::Signature as SecpSignature;
 use bitcoin::secp256k1::Error as SecpError;
 
+use std::convert::TryInto; // Bindings need at least rustc 1.34
+
 #[derive(Clone)]
 #[repr(C)]
 pub struct PublicKey {
@@ -54,8 +57,9 @@ impl Signature {
        pub(crate) fn into_rust(&self) -> SecpSignature {
                SecpSignature::from_compact(&self.compact_form).unwrap()
        }
-       pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
-       pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
+       // The following are used for Option<Signature> which we support, but don't use anymore
+       #[allow(unused)] pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
+       #[allow(unused)] pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
 }
 
 #[repr(C)]
@@ -100,7 +104,8 @@ impl Secp256k1Error {
 /// set. Similarly, while it may change in the future, all `Transaction`s you pass to Rust may have
 /// `data_is_owned` either set or unset at your discretion.
 pub struct Transaction {
-       pub data: *const u8,
+       /// This is non-const for your convenience, an object passed to Rust is never written to.
+       pub data: *mut u8,
        pub datalen: usize,
        pub data_is_owned: bool,
 }
@@ -129,6 +134,10 @@ impl Drop for Transaction {
 #[no_mangle]
 pub extern "C" fn Transaction_free(_res: Transaction) { }
 
+pub(crate) fn bitcoin_to_C_outpoint(outpoint: ::bitcoin::blockdata::transaction::OutPoint) -> crate::chain::transaction::OutPoint {
+       crate::chain::transaction::OutPoint_new(ThirtyTwoBytes { data: outpoint.txid.into_inner() }, outpoint.vout.try_into().unwrap())
+}
+
 #[repr(C)]
 #[derive(Clone)]
 /// A transaction output including a scriptPubKey and value.
@@ -319,90 +328,60 @@ impl<T: Clone> Clone for CVecTempl<T> {
        fn clone(&self) -> Self {
                let mut res = Vec::new();
                if self.datalen == 0 { return Self::from(res); }
-               res.clone_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
+               res.extend_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
                Self::from(res)
        }
 }
 
 #[repr(C)]
 pub struct C2TupleTempl<A, B> {
-       pub a: *mut A,
-       pub b: *mut B,
+       pub a: A,
+       pub b: B,
 }
 impl<A, B> From<(A, B)> for C2TupleTempl<A, B> {
        fn from(tup: (A, B)) -> Self {
                Self {
-                       a: Box::into_raw(Box::new(tup.0)),
-                       b: Box::into_raw(Box::new(tup.1)),
+                       a: tup.0,
+                       b: tup.1,
                }
        }
 }
 impl<A, B> C2TupleTempl<A, B> {
        pub(crate) fn to_rust(mut self) -> (A, B) {
-               let res = (unsafe { *Box::from_raw(self.a) }, unsafe { *Box::from_raw(self.b) });
-               self.a = std::ptr::null_mut();
-               self.b = std::ptr::null_mut();
-               res
+               (self.a, self.b)
        }
 }
 pub extern "C" fn C2TupleTempl_free<A, B>(_res: C2TupleTempl<A, B>) { }
-impl<A, B> Drop for C2TupleTempl<A, B> {
-       fn drop(&mut self) {
-               if !self.a.is_null() {
-                       unsafe { Box::from_raw(self.a) };
-               }
-               if !self.b.is_null() {
-                       unsafe { Box::from_raw(self.b) };
-               }
-       }
-}
 impl <A: Clone, B: Clone> Clone for C2TupleTempl<A, B> {
        fn clone(&self) -> Self {
                Self {
-                       a: Box::into_raw(Box::new(unsafe { &*self.a }.clone())),
-                       b: Box::into_raw(Box::new(unsafe { &*self.b }.clone()))
+                       a: self.a.clone(),
+                       b: self.b.clone()
                }
        }
 }
 
 #[repr(C)]
 pub struct C3TupleTempl<A, B, C> {
-       pub a: *mut A,
-       pub b: *mut B,
-       pub c: *mut C,
+       pub a: A,
+       pub b: B,
+       pub c: C,
 }
 impl<A, B, C> From<(A, B, C)> for C3TupleTempl<A, B, C> {
        fn from(tup: (A, B, C)) -> Self {
                Self {
-                       a: Box::into_raw(Box::new(tup.0)),
-                       b: Box::into_raw(Box::new(tup.1)),
-                       c: Box::into_raw(Box::new(tup.2)),
+                       a: tup.0,
+                       b: tup.1,
+                       c: tup.2,
                }
        }
 }
 impl<A, B, C> C3TupleTempl<A, B, C> {
        pub(crate) fn to_rust(mut self) -> (A, B, C) {
-               let res = (unsafe { *Box::from_raw(self.a) }, unsafe { *Box::from_raw(self.b) }, unsafe { *Box::from_raw(self.c) });
-               self.a = std::ptr::null_mut();
-               self.b = std::ptr::null_mut();
-               self.c = std::ptr::null_mut();
-               res
+               (self.a, self.b, self.c)
        }
 }
 pub extern "C" fn C3TupleTempl_free<A, B, C>(_res: C3TupleTempl<A, B, C>) { }
-impl<A, B, C> Drop for C3TupleTempl<A, B, C> {
-       fn drop(&mut self) {
-               if !self.a.is_null() {
-                       unsafe { Box::from_raw(self.a) };
-               }
-               if !self.b.is_null() {
-                       unsafe { Box::from_raw(self.b) };
-               }
-               if !self.c.is_null() {
-                       unsafe { Box::from_raw(self.c) };
-               }
-       }
-}
 
 /// Utility to make it easy to set a pointer to null and get its original value in line.
 pub(crate) trait TakePointer<T> {