X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-c-bindings%2Fsrc%2Fc_types%2Fmod.rs;h=76807621c2681943c5bcc4712531528b45d9cff3;hb=7dd9d6f40cc5c7d251cc45820e350f669e3e1dfb;hp=813e401b8e7e2b5f567b8791117c815c02aa0d61;hpb=353e29aedd2227a1a3a6811df1d73606f63a687e;p=rust-lightning diff --git a/lightning-c-bindings/src/c_types/mod.rs b/lightning-c-bindings/src/c_types/mod.rs index 813e401b..76807621 100644 --- a/lightning-c-bindings/src/c_types/mod.rs +++ b/lightning-c-bindings/src/c_types/mod.rs @@ -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 { @@ -42,6 +45,7 @@ impl SecretKey { } #[repr(C)] +#[derive(Clone)] pub struct Signature { pub compact_form: [u8; 64], } @@ -54,8 +58,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 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 +105,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, } @@ -122,13 +128,17 @@ impl Transaction { impl Drop for Transaction { fn drop(&mut self) { if self.data_is_owned && self.datalen != 0 { - let _ = CVecTempl { data: self.data as *mut u8, datalen: self.datalen }; + let _ = derived::CVec_u8Z { data: self.data as *mut u8, datalen: self.datalen }; } } } #[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. @@ -147,13 +157,15 @@ impl TxOut { } pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self { Self { - script_pubkey: CVecTempl::from(txout.script_pubkey.into_bytes()), + script_pubkey: derived::CVec_u8Z::from(txout.script_pubkey.into_bytes()), value: txout.value } } } #[no_mangle] pub extern "C" fn TxOut_free(_res: TxOut) { } +#[no_mangle] +pub extern "C" fn TxOut_clone(orig: &TxOut) -> TxOut { orig.clone() } #[repr(C)] pub struct u8slice { @@ -211,11 +223,14 @@ impl lightning::util::ser::Writer for VecWriter { pub(crate) fn serialize_obj(i: &I) -> derived::CVec_u8Z { let mut out = VecWriter(Vec::new()); i.write(&mut out).unwrap(); - CVecTempl::from(out.0) + derived::CVec_u8Z::from(out.0) } pub(crate) fn deserialize_obj(s: u8slice) -> Result { I::read(&mut s.to_slice()) } +pub(crate) fn deserialize_obj_arg>(s: u8slice, args: A) -> Result { + I::read(&mut s.to_slice(), args) +} #[repr(C)] #[derive(Copy, Clone)] @@ -244,14 +259,14 @@ impl Into<&'static str> for Str { // everywhere in the containers. #[repr(C)] -pub union CResultPtr { - pub result: *mut O, - pub err: *mut E, +pub(crate) union CResultPtr { + pub(crate) result: *mut O, + pub(crate) err: *mut E, } #[repr(C)] -pub struct CResultTempl { - pub contents: CResultPtr, - pub result_ok: bool, +pub(crate) struct CResultTempl { + pub(crate) contents: CResultPtr, + pub(crate) result_ok: bool, } impl CResultTempl { pub(crate) extern "C" fn ok(o: O) -> Self { @@ -271,7 +286,6 @@ impl CResultTempl { } } } -pub extern "C" fn CResultTempl_free(_res: CResultTempl) { } impl Drop for CResultTempl { fn drop(&mut self) { if self.result_ok { @@ -284,125 +298,55 @@ impl Drop for CResultTempl { } } -#[repr(C)] -pub struct CVecTempl { - pub data: *mut T, - pub datalen: usize -} -impl CVecTempl { - pub(crate) fn into_rust(&mut self) -> Vec { - if self.datalen == 0 { return Vec::new(); } - let ret = unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }.into(); - self.data = std::ptr::null_mut(); - self.datalen = 0; - ret - } - pub(crate) fn as_slice(&self) -> &[T] { - unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) } - } -} -impl From> for CVecTempl { - fn from(v: Vec) -> Self { - let datalen = v.len(); - let data = Box::into_raw(v.into_boxed_slice()); - CVecTempl { datalen, data: unsafe { (*data).as_mut_ptr() } } - } -} -pub extern "C" fn CVecTempl_free(_res: CVecTempl) { } -impl Drop for CVecTempl { - fn drop(&mut self) { - if self.datalen == 0 { return; } - unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }; - } -} -impl Clone for CVecTempl { - 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) }); - Self::from(res) - } -} - #[repr(C)] pub struct C2TupleTempl { - pub a: *mut A, - pub b: *mut B, + pub a: A, + pub b: B, } impl From<(A, B)> for C2TupleTempl { 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 C2TupleTempl { 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(_res: C2TupleTempl) { } -impl Drop for C2TupleTempl { - 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 Clone for C2TupleTempl { 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 { - pub a: *mut A, - pub b: *mut B, - pub c: *mut C, + pub a: A, + pub b: B, + pub c: C, } impl From<(A, B, C)> for C3TupleTempl { 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 C3TupleTempl { 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(_res: C3TupleTempl) { } -impl Drop for C3TupleTempl { - 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 {