3 use bitcoin::Script as BitcoinScript;
4 use bitcoin::Transaction as BitcoinTransaction;
5 use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;
6 use bitcoin::secp256k1::key::SecretKey as SecpSecretKey;
7 use bitcoin::secp256k1::Signature as SecpSignature;
8 use bitcoin::secp256k1::Error as SecpError;
12 pub struct PublicKey {
13 pub compressed_form: [u8; 33],
16 pub(crate) fn from_rust(pk: &SecpPublicKey) -> Self {
18 compressed_form: pk.serialize(),
21 pub(crate) fn into_rust(&self) -> SecpPublicKey {
22 SecpPublicKey::from_slice(&self.compressed_form).unwrap()
24 pub(crate) fn is_null(&self) -> bool { self.compressed_form[..] == [0; 33][..] }
25 pub(crate) fn null() -> Self { Self { compressed_form: [0; 33] } }
29 pub struct SecretKey {
33 // from_rust isn't implemented for a ref since we just return byte array refs directly
34 pub(crate) fn from_rust(sk: SecpSecretKey) -> Self {
35 let mut bytes = [0; 32];
36 bytes.copy_from_slice(&sk[..]);
39 pub(crate) fn into_rust(&self) -> SecpSecretKey {
40 SecpSecretKey::from_slice(&self.bytes).unwrap()
45 pub struct Signature {
46 pub compact_form: [u8; 64],
49 pub(crate) fn from_rust(pk: &SecpSignature) -> Self {
51 compact_form: pk.serialize_compact(),
54 pub(crate) fn into_rust(&self) -> SecpSignature {
55 SecpSignature::from_compact(&self.compact_form).unwrap()
57 pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
58 pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
62 pub enum Secp256k1Error {
74 pub(crate) fn from_rust(err: SecpError) -> Self {
76 SecpError::IncorrectSignature => Secp256k1Error::IncorrectSignature,
77 SecpError::InvalidMessage => Secp256k1Error::InvalidMessage,
78 SecpError::InvalidPublicKey => Secp256k1Error::InvalidPublicKey,
79 SecpError::InvalidSignature => Secp256k1Error::InvalidSignature,
80 SecpError::InvalidSecretKey => Secp256k1Error::InvalidSecretKey,
81 SecpError::InvalidRecoveryId => Secp256k1Error::InvalidRecoveryId,
82 SecpError::InvalidTweak => Secp256k1Error::InvalidTweak,
83 SecpError::NotEnoughMemory => Secp256k1Error::NotEnoughMemory,
89 /// A serialized transaction, in (pointer, length) form.
91 /// This type optionally owns its own memory, and thus the semantics around access change based on
92 /// the `data_is_owned` flag. If `data_is_owned` is set, you must call `Transaction_free` to free
93 /// the underlying buffer before the object goes out of scope. If `data_is_owned` is not set, any
94 /// access to the buffer after the scope in which the object was provided to you is invalid. eg,
95 /// access after you return from the call in which a `!data_is_owned` `Transaction` is provided to
96 /// you would be invalid.
98 /// Note that, while it may change in the future, because transactions on the Rust side are stored
99 /// in a deserialized form, all `Transaction`s generated on the Rust side will have `data_is_owned`
100 /// set. Similarly, while it may change in the future, all `Transaction`s you pass to Rust may have
101 /// `data_is_owned` either set or unset at your discretion.
102 pub struct Transaction {
105 pub data_is_owned: bool,
108 pub(crate) fn into_bitcoin(&self) -> BitcoinTransaction {
109 if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); }
110 ::bitcoin::consensus::encode::deserialize(unsafe { std::slice::from_raw_parts(self.data, self.datalen) }).unwrap()
112 pub(crate) fn from_vec(v: Vec<u8>) -> Self {
113 let datalen = v.len();
114 let data = Box::into_raw(v.into_boxed_slice());
116 data: unsafe { (*data).as_mut_ptr() },
122 impl Drop for Transaction {
124 if self.data_is_owned && self.datalen != 0 {
125 let _ = CVecTempl { data: self.data as *mut u8, datalen: self.datalen };
130 pub extern "C" fn Transaction_free(_res: Transaction) { }
134 /// A transaction output including a scriptPubKey and value.
135 /// This type *does* own its own memory, so must be free'd appropriately.
137 pub script_pubkey: derived::CVec_u8Z,
142 pub(crate) fn into_rust(mut self) -> ::bitcoin::blockdata::transaction::TxOut {
143 ::bitcoin::blockdata::transaction::TxOut {
144 script_pubkey: self.script_pubkey.into_rust().into(),
148 pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
150 script_pubkey: CVecTempl::from(txout.script_pubkey.into_bytes()),
156 pub extern "C" fn TxOut_free(_res: TxOut) { }
164 pub(crate) fn from_slice(s: &[u8]) -> Self {
170 pub(crate) fn to_slice(&self) -> &[u8] {
171 if self.datalen == 0 { return &[]; }
172 unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
177 #[derive(Copy, Clone)]
178 /// Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
179 /// look up the corresponding function in rust-lightning's docs.
180 pub struct ThirtyTwoBytes {
183 impl ThirtyTwoBytes {
184 pub(crate) fn null() -> Self {
185 Self { data: [0; 32] }
190 pub struct ThreeBytes { pub data: [u8; 3], }
193 pub struct FourBytes { pub data: [u8; 4], }
196 pub struct TenBytes { pub data: [u8; 10], }
199 pub struct SixteenBytes { pub data: [u8; 16], }
201 pub(crate) struct VecWriter(pub Vec<u8>);
202 impl lightning::util::ser::Writer for VecWriter {
203 fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
204 self.0.extend_from_slice(buf);
207 fn size_hint(&mut self, size: usize) {
208 self.0.reserve_exact(size);
211 pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
212 let mut out = VecWriter(Vec::new());
213 i.write(&mut out).unwrap();
214 CVecTempl::from(out.0)
216 pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
217 I::read(&mut s.to_slice())
221 #[derive(Copy, Clone)]
222 /// A Rust str object, ie a reference to a UTF8-valid string.
223 /// This is *not* null-terminated so cannot be used directly as a C string!
225 pub chars: *const u8,
228 impl Into<Str> for &'static str {
229 fn into(self) -> Str {
230 Str { chars: self.as_ptr(), len: self.len() }
233 impl Into<&'static str> for Str {
234 fn into(self) -> &'static str {
235 if self.len == 0 { return ""; }
236 std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap()
240 // Note that the C++ headers memset(0) all the Templ types to avoid deallocation!
241 // Thus, they must gracefully handle being completely null in _free.
243 // TODO: Integer/bool primitives should avoid the pointer indirection for underlying types
244 // everywhere in the containers.
247 pub union CResultPtr<O, E> {
252 pub struct CResultTempl<O, E> {
253 pub contents: CResultPtr<O, E>,
256 impl<O, E> CResultTempl<O, E> {
257 pub(crate) extern "C" fn ok(o: O) -> Self {
259 contents: CResultPtr {
260 result: Box::into_raw(Box::new(o)),
265 pub(crate) extern "C" fn err(e: E) -> Self {
267 contents: CResultPtr {
268 err: Box::into_raw(Box::new(e)),
274 pub extern "C" fn CResultTempl_free<O, E>(_res: CResultTempl<O, E>) { }
275 impl<O, E> Drop for CResultTempl<O, E> {
278 if unsafe { !self.contents.result.is_null() } {
279 unsafe { Box::from_raw(self.contents.result) };
281 } else if unsafe { !self.contents.err.is_null() } {
282 unsafe { Box::from_raw(self.contents.err) };
288 pub struct CVecTempl<T> {
292 impl<T> CVecTempl<T> {
293 pub(crate) fn into_rust(&mut self) -> Vec<T> {
294 if self.datalen == 0 { return Vec::new(); }
295 let ret = unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }.into();
296 self.data = std::ptr::null_mut();
300 pub(crate) fn as_slice(&self) -> &[T] {
301 unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) }
304 impl<T> From<Vec<T>> for CVecTempl<T> {
305 fn from(v: Vec<T>) -> Self {
306 let datalen = v.len();
307 let data = Box::into_raw(v.into_boxed_slice());
308 CVecTempl { datalen, data: unsafe { (*data).as_mut_ptr() } }
311 pub extern "C" fn CVecTempl_free<T>(_res: CVecTempl<T>) { }
312 impl<T> Drop for CVecTempl<T> {
314 if self.datalen == 0 { return; }
315 unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) };
318 impl<T: Clone> Clone for CVecTempl<T> {
319 fn clone(&self) -> Self {
320 let mut res = Vec::new();
321 if self.datalen == 0 { return Self::from(res); }
322 res.clone_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
328 pub struct C2TupleTempl<A, B> {
332 impl<A, B> From<(A, B)> for C2TupleTempl<A, B> {
333 fn from(tup: (A, B)) -> Self {
340 impl<A, B> C2TupleTempl<A, B> {
341 pub(crate) fn to_rust(mut self) -> (A, B) {
345 pub extern "C" fn C2TupleTempl_free<A, B>(_res: C2TupleTempl<A, B>) { }
346 impl <A: Clone, B: Clone> Clone for C2TupleTempl<A, B> {
347 fn clone(&self) -> Self {
356 pub struct C3TupleTempl<A, B, C> {
361 impl<A, B, C> From<(A, B, C)> for C3TupleTempl<A, B, C> {
362 fn from(tup: (A, B, C)) -> Self {
370 impl<A, B, C> C3TupleTempl<A, B, C> {
371 pub(crate) fn to_rust(mut self) -> (A, B, C) {
372 (self.a, self.b, self.c)
375 pub extern "C" fn C3TupleTempl_free<A, B, C>(_res: C3TupleTempl<A, B, C>) { }
377 /// Utility to make it easy to set a pointer to null and get its original value in line.
378 pub(crate) trait TakePointer<T> {
379 fn take_ptr(&mut self) -> T;
381 impl<T> TakePointer<*const T> for *const T {
382 fn take_ptr(&mut self) -> *const T {
384 *self = std::ptr::null();
388 impl<T> TakePointer<*mut T> for *mut T {
389 fn take_ptr(&mut self) -> *mut T {
391 *self = std::ptr::null_mut();