Merge pull request #11 from TheBlueMatt/2021-04-upstream-bump
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Tue, 13 Apr 2021 01:54:49 +0000 (01:54 +0000)
committerGitHub <noreply@github.com>
Tue, 13 Apr 2021 01:54:49 +0000 (01:54 +0000)
Bump Upstream and clean up supertrait handling

13 files changed:
c-bindings-gen/src/main.rs
c-bindings-gen/src/types.rs
lightning-c-bindings/Cargo.toml
lightning-c-bindings/demo.cpp
lightning-c-bindings/include/lightning.h
lightning-c-bindings/include/lightningpp.hpp
lightning-c-bindings/include/rust_types.h
lightning-c-bindings/src/chain/keysinterface.rs
lightning-c-bindings/src/ln/channelmanager.rs
lightning-c-bindings/src/ln/msgs.rs
lightning-c-bindings/src/ln/peer_handler.rs
lightning-c-bindings/src/routing/network_graph.rs
lightning-c-bindings/src/util/events.rs

index 1d37bb2b6335c4a538511b13345d5f01be36a5bc..f0c5db39982a7101cf82a459c07dbf8053d1f751 100644 (file)
 //! It also generates relevant memory-management functions and free-standing functions with
 //! parameters mapped.
 
-use std::collections::{HashMap, hash_map, HashSet};
+use std::collections::{HashMap, hash_map};
 use std::env;
 use std::fs::File;
 use std::io::{Read, Write};
 use std::process;
 
-use proc_macro2::{TokenTree, TokenStream, Span};
+use proc_macro2::Span;
 
 mod types;
 mod blocks;
@@ -35,38 +35,6 @@ use blocks::*;
 // *** Manually-expanded conversions ***
 // *************************************
 
-/// Because we don't expand macros, any code that we need to generated based on their contents has
-/// to be completely manual. In this case its all just serialization, so its not too hard.
-fn convert_macro<W: std::io::Write>(w: &mut W, macro_path: &syn::Path, stream: &TokenStream, types: &TypeResolver) {
-       assert_eq!(macro_path.segments.len(), 1);
-       match &format!("{}", macro_path.segments.iter().next().unwrap().ident) as &str {
-               "impl_writeable" | "impl_writeable_len_match" => {
-                       let struct_for = if let TokenTree::Ident(i) = stream.clone().into_iter().next().unwrap() { i } else { unimplemented!(); };
-                       if let Some(s) = types.maybe_resolve_ident(&struct_for) {
-                               if !types.crate_types.opaques.get(&s).is_some() { return; }
-                               writeln!(w, "#[no_mangle]").unwrap();
-                               writeln!(w, "/// Serialize the {} into a byte array which can be read by {}_read", struct_for, struct_for).unwrap();
-                               writeln!(w, "pub extern \"C\" fn {}_write(obj: &{}) -> crate::c_types::derived::CVec_u8Z {{", struct_for, struct_for).unwrap();
-                               writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &(*(*obj).inner) }})").unwrap();
-                               writeln!(w, "}}").unwrap();
-                               writeln!(w, "#[no_mangle]").unwrap();
-                               writeln!(w, "pub(crate) extern \"C\" fn {}_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {{", struct_for).unwrap();
-                               writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &*(obj as *const native{}) }})", struct_for).unwrap();
-                               writeln!(w, "}}").unwrap();
-                               writeln!(w, "#[no_mangle]").unwrap();
-                               writeln!(w, "/// Read a {} from a byte array, created by {}_write", struct_for, struct_for).unwrap();
-                               writeln!(w, "pub extern \"C\" fn {}_read(ser: crate::c_types::u8slice) -> {} {{", struct_for, struct_for).unwrap();
-                               writeln!(w, "\tif let Ok(res) = crate::c_types::deserialize_obj(ser) {{").unwrap();
-                               writeln!(w, "\t\t{} {{ inner: Box::into_raw(Box::new(res)), is_owned: true }}", struct_for).unwrap();
-                               writeln!(w, "\t}} else {{").unwrap();
-                               writeln!(w, "\t\t{} {{ inner: std::ptr::null_mut(), is_owned: true }}", struct_for).unwrap();
-                               writeln!(w, "\t}}\n}}").unwrap();
-                       }
-               },
-               _ => {},
-       }
-}
-
 /// Convert "impl trait_path for for_ty { .. }" for manually-mapped types (ie (de)serialization)
 fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path, for_ty: &syn::Type, types: &mut TypeResolver, generics: &GenericTypes) {
        if let Some(t) = types.maybe_resolve_path(&trait_path, Some(generics)) {
@@ -211,14 +179,9 @@ fn write_trait_impl_field_assign<W: std::io::Write>(w: &mut W, trait_path: &str,
 }
 
 /// Write out the impl block for a defined trait struct which has a supertrait
-fn do_write_impl_trait<W: std::io::Write>(w: &mut W, trait_path: &str, trait_name: &syn::Ident, for_obj: &str) {
+fn do_write_impl_trait<W: std::io::Write>(w: &mut W, trait_path: &str, _trait_name: &syn::Ident, for_obj: &str) {
+eprintln!("{}", trait_path);
        match trait_path {
-               "util::events::MessageSendEventsProvider" => {
-                       writeln!(w, "impl lightning::{} for {} {{", trait_path, for_obj).unwrap();
-                       writeln!(w, "\tfn get_and_clear_pending_msg_events(&self) -> Vec<lightning::util::events::MessageSendEvent> {{").unwrap();
-                       writeln!(w, "\t\t<crate::{} as lightning::{}>::get_and_clear_pending_msg_events(&self.{})", trait_path, trait_path, trait_name).unwrap();
-                       writeln!(w, "\t}}\n}}").unwrap();
-               },
                "util::ser::Writeable" => {
                        writeln!(w, "impl lightning::{} for {} {{", trait_path, for_obj).unwrap();
                        writeln!(w, "\tfn write<W: lightning::util::ser::Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {{").unwrap();
@@ -289,7 +252,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
        writeln!(w, "\t/// An opaque pointer which is passed to your function implementations as an argument.").unwrap();
        writeln!(w, "\t/// This has no meaning in the LDK, and can be NULL or any other value.").unwrap();
        writeln!(w, "\tpub this_arg: *mut c_void,").unwrap();
-       let mut generated_fields = Vec::new(); // Every field's name except this_arg, used in Clone generation
+       let mut generated_fields = Vec::new(); // Every field's (name, is_clonable) except this_arg, used in Clone generation
        for item in t.items.iter() {
                match item {
                        &syn::TraitItem::Method(ref m) => {
@@ -304,8 +267,8 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                }
                                if m.default.is_some() { unimplemented!(); }
 
-                               gen_types.push_ctx();
-                               assert!(gen_types.learn_generics(&m.sig.generics, types));
+                               let mut meth_gen_types = gen_types.push_ctx();
+                               assert!(meth_gen_types.learn_generics(&m.sig.generics, types));
 
                                writeln_docs(w, &m.attrs, "\t");
 
@@ -322,20 +285,19 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                // happen) as well as provide an Option<>al function pointer which is
                                                // called when the trait method is called which allows updating on the fly.
                                                write!(w, "\tpub {}: ", m.sig.ident).unwrap();
-                                               generated_fields.push(format!("{}", m.sig.ident));
-                                               types.write_c_type(w, &*r.elem, Some(&gen_types), false);
+                                               generated_fields.push((format!("{}", m.sig.ident), true));
+                                               types.write_c_type(w, &*r.elem, Some(&meth_gen_types), false);
                                                writeln!(w, ",").unwrap();
                                                writeln!(w, "\t/// Fill in the {} field as a reference to it will be given to Rust after this returns", m.sig.ident).unwrap();
                                                writeln!(w, "\t/// Note that this takes a pointer to this object, not the this_ptr like other methods do").unwrap();
                                                writeln!(w, "\t/// This function pointer may be NULL if {} is filled in when this object is created and never needs updating.", m.sig.ident).unwrap();
                                                writeln!(w, "\tpub set_{}: Option<extern \"C\" fn(&{})>,", m.sig.ident, trait_name).unwrap();
-                                               generated_fields.push(format!("set_{}", m.sig.ident));
+                                               generated_fields.push((format!("set_{}", m.sig.ident), true));
                                                // Note that cbindgen will now generate
                                                // typedef struct Thing {..., set_thing: (const Thing*), ...} Thing;
                                                // which does not compile since Thing is not defined before it is used.
                                                writeln!(extra_headers, "struct LDK{};", trait_name).unwrap();
                                                writeln!(extra_headers, "typedef struct LDK{} LDK{};", trait_name, trait_name).unwrap();
-                                               gen_types.pop_ctx();
                                                continue;
                                        }
                                        // Sadly, this currently doesn't do what we want, but it should be easy to get
@@ -344,36 +306,39 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                }
 
                                write!(w, "\tpub {}: extern \"C\" fn (", m.sig.ident).unwrap();
-                               generated_fields.push(format!("{}", m.sig.ident));
-                               write_method_params(w, &m.sig, "c_void", types, Some(&gen_types), true, false);
+                               generated_fields.push((format!("{}", m.sig.ident), true));
+                               write_method_params(w, &m.sig, "c_void", types, Some(&meth_gen_types), true, false);
                                writeln!(w, ",").unwrap();
-
-                               gen_types.pop_ctx();
                        },
                        &syn::TraitItem::Type(_) => {},
                        _ => unimplemented!(),
                }
        }
        // Add functions which may be required for supertrait implementations.
+       let mut requires_clone = false;
+       walk_supertraits!(t, Some(&types), (
+               ("Clone", _) => requires_clone = true,
+               (_, _) => {}
+       ) );
        walk_supertraits!(t, Some(&types), (
                ("Clone", _) => {
                        writeln!(w, "\t/// Creates a copy of the object pointed to by this_arg, for a copy of this {}.", trait_name).unwrap();
                        writeln!(w, "\t/// Note that the ultimate copy of the {} will have all function pointers the same as the original.", trait_name).unwrap();
                        writeln!(w, "\t/// May be NULL if no action needs to be taken, the this_arg pointer will be copied into the new {}.", trait_name).unwrap();
                        writeln!(w, "\tpub clone: Option<extern \"C\" fn (this_arg: *const c_void) -> *mut c_void>,").unwrap();
-                       generated_fields.push("clone".to_owned());
+                       generated_fields.push(("clone".to_owned(), true));
                },
                ("std::cmp::Eq", _) => {
                        writeln!(w, "\t/// Checks if two objects are equal given this object's this_arg pointer and another object.").unwrap();
                        writeln!(w, "\tpub eq: extern \"C\" fn (this_arg: *const c_void, other_arg: &{}) -> bool,", trait_name).unwrap();
                        writeln!(extra_headers, "typedef struct LDK{} LDK{};", trait_name, trait_name).unwrap();
-                       generated_fields.push("eq".to_owned());
+                       generated_fields.push(("eq".to_owned(), true));
                },
                ("std::hash::Hash", _) => {
                        writeln!(w, "\t/// Calculate a succinct non-cryptographic hash for an object given its this_arg pointer.").unwrap();
                        writeln!(w, "\t/// This is used, for example, for inclusion of this object in a hash map.").unwrap();
                        writeln!(w, "\tpub hash: extern \"C\" fn (this_arg: *const c_void) -> u64,").unwrap();
-                       generated_fields.push("hash".to_owned());
+                       generated_fields.push(("hash".to_owned(), true));
                },
                ("Send", _) => {}, ("Sync", _) => {},
                (s, i) => {
@@ -381,20 +346,125 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                let (docs, name, ret) = convert_trait_impl_field(s);
                                writeln!(w, "\t/// {}", docs).unwrap();
                                writeln!(w, "\tpub {}: extern \"C\" fn (this_arg: *const c_void) -> {},", name, ret).unwrap();
-                               name
+                               (name, true) // Assume clonable
                        } else {
                                // For in-crate supertraits, just store a C-mapped copy of the supertrait as a member.
-                               writeln!(w, "/// Implementation of {} for this object.", i).unwrap();
+                               writeln!(w, "\t/// Implementation of {} for this object.", i).unwrap();
                                writeln!(w, "\tpub {}: crate::{},", i, s).unwrap();
-                               format!("{}", i)
+                               let is_clonable = types.is_clonable(s);
+                               if !is_clonable && requires_clone {
+                                       writeln!(w, "\t/// Creates a copy of the {}, for a copy of this {}.", i, trait_name).unwrap();
+                                       writeln!(w, "\t/// Because {} doesn't natively support copying itself, you have to provide a full copy implementation here.", i).unwrap();
+                                       writeln!(w, "\tpub {}_clone: extern \"C\" fn (orig_{}: &{}) -> {},", i, i, i, i).unwrap();
+                               }
+                               (format!("{}", i), is_clonable)
                        });
                }
        ) );
        writeln!(w, "\t/// Frees any resources associated with this object given its this_arg pointer.").unwrap();
        writeln!(w, "\t/// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed.").unwrap();
        writeln!(w, "\tpub free: Option<extern \"C\" fn(this_arg: *mut c_void)>,").unwrap();
-       generated_fields.push("free".to_owned());
+       generated_fields.push(("free".to_owned(), true));
        writeln!(w, "}}").unwrap();
+
+       macro_rules! impl_trait_for_c {
+               ($t: expr, $impl_accessor: expr, $type_resolver: expr) => {
+                       for item in $t.items.iter() {
+                               match item {
+                                       syn::TraitItem::Method(m) => {
+                                               if let ExportStatus::TestOnly = export_status(&m.attrs) { continue; }
+                                               if m.default.is_some() { unimplemented!(); }
+                                               if m.sig.constness.is_some() || m.sig.asyncness.is_some() || m.sig.unsafety.is_some() ||
+                                                               m.sig.abi.is_some() || m.sig.variadic.is_some() {
+                                                       unimplemented!();
+                                               }
+                                               let mut meth_gen_types = gen_types.push_ctx();
+                                               assert!(meth_gen_types.learn_generics(&m.sig.generics, $type_resolver));
+                                               write!(w, "\tfn {}", m.sig.ident).unwrap();
+                                               $type_resolver.write_rust_generic_param(w, Some(&meth_gen_types), m.sig.generics.params.iter());
+                                               write!(w, "(").unwrap();
+                                               for inp in m.sig.inputs.iter() {
+                                                       match inp {
+                                                               syn::FnArg::Receiver(recv) => {
+                                                                       if !recv.attrs.is_empty() || recv.reference.is_none() { unimplemented!(); }
+                                                                       write!(w, "&").unwrap();
+                                                                       if let Some(lft) = &recv.reference.as_ref().unwrap().1 {
+                                                                               write!(w, "'{} ", lft.ident).unwrap();
+                                                                       }
+                                                                       if recv.mutability.is_some() {
+                                                                               write!(w, "mut self").unwrap();
+                                                                       } else {
+                                                                               write!(w, "self").unwrap();
+                                                                       }
+                                                               },
+                                                               syn::FnArg::Typed(arg) => {
+                                                                       if !arg.attrs.is_empty() { unimplemented!(); }
+                                                                       match &*arg.pat {
+                                                                               syn::Pat::Ident(ident) => {
+                                                                                       if !ident.attrs.is_empty() || ident.by_ref.is_some() ||
+                                                                                                       ident.mutability.is_some() || ident.subpat.is_some() {
+                                                                                               unimplemented!();
+                                                                                       }
+                                                                                       write!(w, ", {}{}: ", if $type_resolver.skip_arg(&*arg.ty, Some(&meth_gen_types)) { "_" } else { "" }, ident.ident).unwrap();
+                                                                               }
+                                                                               _ => unimplemented!(),
+                                                                       }
+                                                                       $type_resolver.write_rust_type(w, Some(&meth_gen_types), &*arg.ty);
+                                                               }
+                                                       }
+                                               }
+                                               write!(w, ")").unwrap();
+                                               match &m.sig.output {
+                                                       syn::ReturnType::Type(_, rtype) => {
+                                                               write!(w, " -> ").unwrap();
+                                                               $type_resolver.write_rust_type(w, Some(&meth_gen_types), &*rtype)
+                                                       },
+                                                       _ => {},
+                                               }
+                                               write!(w, " {{\n\t\t").unwrap();
+                                               match export_status(&m.attrs) {
+                                                       ExportStatus::NoExport => {
+                                                               unimplemented!();
+                                                       },
+                                                       _ => {},
+                                               }
+                                               if let syn::ReturnType::Type(_, rtype) = &m.sig.output {
+                                                       if let syn::Type::Reference(r) = &**rtype {
+                                                               assert_eq!(m.sig.inputs.len(), 1); // Must only take self!
+                                                               writeln!(w, "if let Some(f) = self{}.set_{} {{", $impl_accessor, m.sig.ident).unwrap();
+                                                               writeln!(w, "\t\t\t(f)(&self{});", $impl_accessor).unwrap();
+                                                               write!(w, "\t\t}}\n\t\t").unwrap();
+                                                               $type_resolver.write_from_c_conversion_to_ref_prefix(w, &*r.elem, Some(&meth_gen_types));
+                                                               write!(w, "self{}.{}", $impl_accessor, m.sig.ident).unwrap();
+                                                               $type_resolver.write_from_c_conversion_to_ref_suffix(w, &*r.elem, Some(&meth_gen_types));
+                                                               writeln!(w, "\n\t}}").unwrap();
+                                                               continue;
+                                                       }
+                                               }
+                                               write_method_var_decl_body(w, &m.sig, "\t", $type_resolver, Some(&meth_gen_types), true);
+                                               write!(w, "(self{}.{})(", $impl_accessor, m.sig.ident).unwrap();
+                                               write_method_call_params(w, &m.sig, "\t", $type_resolver, Some(&meth_gen_types), "", true);
+
+                                               writeln!(w, "\n\t}}").unwrap();
+                                       },
+                                       &syn::TraitItem::Type(ref t) => {
+                                               if t.default.is_some() || t.generics.lt_token.is_some() { unimplemented!(); }
+                                               let mut bounds_iter = t.bounds.iter();
+                                               match bounds_iter.next().unwrap() {
+                                                       syn::TypeParamBound::Trait(tr) => {
+                                                               writeln!(w, "\ttype {} = crate::{};", t.ident, $type_resolver.resolve_path(&tr.path, Some(&gen_types))).unwrap();
+                                                       },
+                                                       _ => unimplemented!(),
+                                               }
+                                               if bounds_iter.next().is_some() { unimplemented!(); }
+                                       },
+                                       _ => unimplemented!(),
+                               }
+                       }
+               }
+       }
+
+
        // Implement supertraits for the C-mapped struct.
        walk_supertraits!(t, Some(&types), (
                ("Send", _) => writeln!(w, "unsafe impl Send for {} {{}}", trait_name).unwrap(),
@@ -414,8 +484,13 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                        writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", trait_name, trait_name, trait_name).unwrap();
                        writeln!(w, "\t{} {{", trait_name).unwrap();
                        writeln!(w, "\t\tthis_arg: if let Some(f) = orig.clone {{ (f)(orig.this_arg) }} else {{ orig.this_arg }},").unwrap();
-                       for field in generated_fields.iter() {
-                               writeln!(w, "\t\t{}: orig.{}.clone(),", field, field).unwrap();
+                       for (field, clonable) in generated_fields.iter() {
+                               if *clonable {
+                                       writeln!(w, "\t\t{}: Clone::clone(&orig.{}),", field, field).unwrap();
+                               } else {
+                                       writeln!(w, "\t\t{}: (orig.{}_clone)(&orig.{}),", field, field, field).unwrap();
+                                       writeln!(w, "\t\t{}_clone: orig.{}_clone,", field, field).unwrap();
+                               }
                        }
                        writeln!(w, "\t}}\n}}").unwrap();
                        writeln!(w, "impl Clone for {} {{", trait_name).unwrap();
@@ -424,7 +499,23 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                        writeln!(w, "\t}}\n}}").unwrap();
                },
                (s, i) => {
-                       do_write_impl_trait(w, s, i, &trait_name);
+                       if let Some(supertrait) = types.crate_types.traits.get(s) {
+                               let mut module_iter = s.rsplitn(2, "::");
+                               module_iter.next().unwrap();
+                               let supertrait_module = module_iter.next().unwrap();
+                               let imports = ImportResolver::new(supertrait_module, &types.crate_types.lib_ast.modules.get(supertrait_module).unwrap().items);
+                               let resolver = TypeResolver::new("lightning", &supertrait_module, imports, types.crate_types); // TODO: Drop hard-coded crate name here
+                               writeln!(w, "impl lightning::{} for {} {{", s, trait_name).unwrap(); // TODO: Drop hard-coded crate name here
+                               impl_trait_for_c!(supertrait, format!(".{}", i), &resolver);
+                               writeln!(w, "}}").unwrap();
+                               walk_supertraits!(supertrait, Some(&types), (
+                                       ("Send", _) => writeln!(w, "unsafe impl Send for {} {{}}", trait_name).unwrap(),
+                                       ("Sync", _) => writeln!(w, "unsafe impl Sync for {} {{}}", trait_name).unwrap(),
+                                       _ => unimplemented!()
+                               ) );
+                       } else {
+                               do_write_impl_trait(w, s, i, &trait_name);
+                       }
                }
        ) );
 
@@ -433,100 +524,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
        write!(w, "impl rust{}", t.ident).unwrap();
        maybe_write_generics(w, &t.generics, types, false);
        writeln!(w, " for {} {{", trait_name).unwrap();
-       for item in t.items.iter() {
-               match item {
-                       syn::TraitItem::Method(m) => {
-                               if let ExportStatus::TestOnly = export_status(&m.attrs) { continue; }
-                               if m.default.is_some() { unimplemented!(); }
-                               if m.sig.constness.is_some() || m.sig.asyncness.is_some() || m.sig.unsafety.is_some() ||
-                                               m.sig.abi.is_some() || m.sig.variadic.is_some() {
-                                       unimplemented!();
-                               }
-                               gen_types.push_ctx();
-                               assert!(gen_types.learn_generics(&m.sig.generics, types));
-                               write!(w, "\tfn {}", m.sig.ident).unwrap();
-                               types.write_rust_generic_param(w, Some(&gen_types), m.sig.generics.params.iter());
-                               write!(w, "(").unwrap();
-                               for inp in m.sig.inputs.iter() {
-                                       match inp {
-                                               syn::FnArg::Receiver(recv) => {
-                                                       if !recv.attrs.is_empty() || recv.reference.is_none() { unimplemented!(); }
-                                                       write!(w, "&").unwrap();
-                                                       if let Some(lft) = &recv.reference.as_ref().unwrap().1 {
-                                                               write!(w, "'{} ", lft.ident).unwrap();
-                                                       }
-                                                       if recv.mutability.is_some() {
-                                                               write!(w, "mut self").unwrap();
-                                                       } else {
-                                                               write!(w, "self").unwrap();
-                                                       }
-                                               },
-                                               syn::FnArg::Typed(arg) => {
-                                                       if !arg.attrs.is_empty() { unimplemented!(); }
-                                                       match &*arg.pat {
-                                                               syn::Pat::Ident(ident) => {
-                                                                       if !ident.attrs.is_empty() || ident.by_ref.is_some() ||
-                                                                                       ident.mutability.is_some() || ident.subpat.is_some() {
-                                                                               unimplemented!();
-                                                                       }
-                                                                       write!(w, ", {}{}: ", if types.skip_arg(&*arg.ty, Some(&gen_types)) { "_" } else { "" }, ident.ident).unwrap();
-                                                               }
-                                                               _ => unimplemented!(),
-                                                       }
-                                                       types.write_rust_type(w, Some(&gen_types), &*arg.ty);
-                                               }
-                                       }
-                               }
-                               write!(w, ")").unwrap();
-                               match &m.sig.output {
-                                       syn::ReturnType::Type(_, rtype) => {
-                                               write!(w, " -> ").unwrap();
-                                               types.write_rust_type(w, Some(&gen_types), &*rtype)
-                                       },
-                                       _ => {},
-                               }
-                               write!(w, " {{\n\t\t").unwrap();
-                               match export_status(&m.attrs) {
-                                       ExportStatus::NoExport => {
-                                               unimplemented!();
-                                       },
-                                       _ => {},
-                               }
-                               if let syn::ReturnType::Type(_, rtype) = &m.sig.output {
-                                       if let syn::Type::Reference(r) = &**rtype {
-                                               assert_eq!(m.sig.inputs.len(), 1); // Must only take self!
-                                               writeln!(w, "if let Some(f) = self.set_{} {{", m.sig.ident).unwrap();
-                                               writeln!(w, "\t\t\t(f)(self);").unwrap();
-                                               write!(w, "\t\t}}\n\t\t").unwrap();
-                                               types.write_from_c_conversion_to_ref_prefix(w, &*r.elem, Some(&gen_types));
-                                               write!(w, "self.{}", m.sig.ident).unwrap();
-                                               types.write_from_c_conversion_to_ref_suffix(w, &*r.elem, Some(&gen_types));
-                                               writeln!(w, "\n\t}}").unwrap();
-                                               gen_types.pop_ctx();
-                                               continue;
-                                       }
-                               }
-                               write_method_var_decl_body(w, &m.sig, "\t", types, Some(&gen_types), true);
-                               write!(w, "(self.{})(", m.sig.ident).unwrap();
-                               write_method_call_params(w, &m.sig, "\t", types, Some(&gen_types), "", true);
-
-                               writeln!(w, "\n\t}}").unwrap();
-                               gen_types.pop_ctx();
-                       },
-                       &syn::TraitItem::Type(ref t) => {
-                               if t.default.is_some() || t.generics.lt_token.is_some() { unimplemented!(); }
-                               let mut bounds_iter = t.bounds.iter();
-                               match bounds_iter.next().unwrap() {
-                                       syn::TypeParamBound::Trait(tr) => {
-                                               writeln!(w, "\ttype {} = crate::{};", t.ident, types.resolve_path(&tr.path, Some(&gen_types))).unwrap();
-                                       },
-                                       _ => unimplemented!(),
-                               }
-                               if bounds_iter.next().is_some() { unimplemented!(); }
-                       },
-                       _ => unimplemented!(),
-               }
-       }
+       impl_trait_for_c!(t, "", types);
        writeln!(w, "}}\n").unwrap();
        writeln!(w, "// We're essentially a pointer already, or at least a set of pointers, so allow us to be used").unwrap();
        writeln!(w, "// directly as a Deref trait in higher-level structs:").unwrap();
@@ -802,12 +800,12 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                        if let syn::Type::Reference(r) = &**rtype {
                                                                                write!(w, "\n\t\t{}{}: ", $indent, $m.sig.ident).unwrap();
                                                                                types.write_empty_rust_val(Some(&gen_types), w, &*r.elem);
-                                                                               writeln!(w, ",\n{}\t\tset_{}: Some({}_{}_set_{}),", $indent, $m.sig.ident, ident, trait_obj.ident, $m.sig.ident).unwrap();
+                                                                               writeln!(w, ",\n{}\t\tset_{}: Some({}_{}_set_{}),", $indent, $m.sig.ident, ident, $trait.ident, $m.sig.ident).unwrap();
                                                                                printed = true;
                                                                        }
                                                                }
                                                                if !printed {
-                                                                       write!(w, "{}\t\t{}: {}_{}_{},\n", $indent, $m.sig.ident, ident, trait_obj.ident, $m.sig.ident).unwrap();
+                                                                       write!(w, "{}\t\t{}: {}_{}_{},\n", $indent, $m.sig.ident, ident, $trait.ident, $m.sig.ident).unwrap();
                                                                }
                                                        }
                                                }
@@ -819,6 +817,11 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                _ => {},
                                                        }
                                                }
+                                               let mut requires_clone = false;
+                                               walk_supertraits!(trait_obj, Some(&types), (
+                                                       ("Clone", _) => requires_clone = true,
+                                                       (_, _) => {}
+                                               ) );
                                                walk_supertraits!(trait_obj, Some(&types), (
                                                        ("Clone", _) => {
                                                                writeln!(w, "\t\tclone: Some({}_clone_void),", ident).unwrap();
@@ -839,6 +842,9 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                                }
                                                                        }
                                                                        write!(w, "\t\t}},\n").unwrap();
+                                                                       if !types.is_clonable(s) && requires_clone {
+                                                                               writeln!(w, "\t\t{}_clone: {}_{}_clone,", t, ident, t).unwrap();
+                                                                       }
                                                                } else {
                                                                        write_trait_impl_field_assign(w, s, ident);
                                                                }
@@ -859,12 +865,12 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                if let syn::ReturnType::Type(_, _) = &$m.sig.output {
                                                                        writeln!(w, "#[must_use]").unwrap();
                                                                }
-                                                               write!(w, "extern \"C\" fn {}_{}_{}(", ident, trait_obj.ident, $m.sig.ident).unwrap();
-                                                               gen_types.push_ctx();
-                                                               assert!(gen_types.learn_generics(&$m.sig.generics, types));
-                                                               write_method_params(w, &$m.sig, "c_void", types, Some(&gen_types), true, true);
+                                                               write!(w, "extern \"C\" fn {}_{}_{}(", ident, $trait.ident, $m.sig.ident).unwrap();
+                                                               let mut meth_gen_types = gen_types.push_ctx();
+                                                               assert!(meth_gen_types.learn_generics(&$m.sig.generics, types));
+                                                               write_method_params(w, &$m.sig, "c_void", types, Some(&meth_gen_types), true, true);
                                                                write!(w, " {{\n\t").unwrap();
-                                                               write_method_var_decl_body(w, &$m.sig, "", types, Some(&gen_types), false);
+                                                               write_method_var_decl_body(w, &$m.sig, "", types, Some(&meth_gen_types), false);
                                                                let mut takes_self = false;
                                                                for inp in $m.sig.inputs.iter() {
                                                                        if let syn::FnArg::Receiver(_) = inp {
@@ -894,19 +900,18 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                        },
                                                                        _ => {},
                                                                }
-                                                               write_method_call_params(w, &$m.sig, "", types, Some(&gen_types), &real_type, false);
-                                                               gen_types.pop_ctx();
+                                                               write_method_call_params(w, &$m.sig, "", types, Some(&meth_gen_types), &real_type, false);
                                                                write!(w, "\n}}\n").unwrap();
                                                                if let syn::ReturnType::Type(_, rtype) = &$m.sig.output {
                                                                        if let syn::Type::Reference(r) = &**rtype {
                                                                                assert_eq!($m.sig.inputs.len(), 1); // Must only take self
-                                                                               writeln!(w, "extern \"C\" fn {}_{}_set_{}(trait_self_arg: &{}) {{", ident, trait_obj.ident, $m.sig.ident, trait_obj.ident).unwrap();
+                                                                               writeln!(w, "extern \"C\" fn {}_{}_set_{}(trait_self_arg: &{}) {{", ident, $trait.ident, $m.sig.ident, $trait.ident).unwrap();
                                                                                writeln!(w, "\t// This is a bit race-y in the general case, but for our specific use-cases today, we're safe").unwrap();
                                                                                writeln!(w, "\t// Specifically, we must ensure that the first time we're called it can never be in parallel").unwrap();
                                                                                write!(w, "\tif ").unwrap();
-                                                                               types.write_empty_rust_val_check(Some(&gen_types), w, &*r.elem, &format!("trait_self_arg.{}", $m.sig.ident));
+                                                                               types.write_empty_rust_val_check(Some(&meth_gen_types), w, &*r.elem, &format!("trait_self_arg.{}", $m.sig.ident));
                                                                                writeln!(w, " {{").unwrap();
-                                                                               writeln!(w, "\t\tunsafe {{ &mut *(trait_self_arg as *const {}  as *mut {}) }}.{} = {}_{}_{}(trait_self_arg.this_arg);", trait_obj.ident, trait_obj.ident, $m.sig.ident, ident, trait_obj.ident, $m.sig.ident).unwrap();
+                                                                               writeln!(w, "\t\tunsafe {{ &mut *(trait_self_arg as *const {}  as *mut {}) }}.{} = {}_{}_{}(trait_self_arg.this_arg);", $trait.ident, $trait.ident, $m.sig.ident, ident, $trait.ident, $m.sig.ident).unwrap();
                                                                                writeln!(w, "\t}}").unwrap();
                                                                                writeln!(w, "}}").unwrap();
                                                                        }
@@ -924,15 +929,22 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                        }
                                                }
                                                walk_supertraits!(trait_obj, Some(&types), (
-                                                       (s, _) => {
-                                                               if let Some(supertrait_obj) = types.crate_types.traits.get(s).cloned() {
-                                                                       for item in supertrait_obj.items.iter() {
-                                                                               match item {
-                                                                                       syn::TraitItem::Method(m) => {
-                                                                                               impl_meth!(m, s, supertrait_obj, "\t");
-                                                                                       },
-                                                                                       _ => {},
+                                                       (s, t) => {
+                                                               if let Some(supertrait_obj) = types.crate_types.traits.get(s) {
+                                                                       if !types.is_clonable(s) && requires_clone {
+                                                                               writeln!(w, "extern \"C\" fn {}_{}_clone(orig: &crate::{}) -> crate::{} {{", ident, t, s, s).unwrap();
+                                                                               writeln!(w, "\tcrate::{} {{", s).unwrap();
+                                                                               writeln!(w, "\t\tthis_arg: orig.this_arg,").unwrap();
+                                                                               writeln!(w, "\t\tfree: None,").unwrap();
+                                                                               for item in supertrait_obj.items.iter() {
+                                                                                       match item {
+                                                                                               syn::TraitItem::Method(m) => {
+                                                                                                       write_meth!(m, supertrait_obj, "");
+                                                                                               },
+                                                                                               _ => {},
+                                                                                       }
                                                                                }
+                                                                               write!(w, "\t}}\n}}\n").unwrap();
                                                                        }
                                                                }
                                                        }
@@ -990,11 +1002,11 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                                DeclType::StructImported => format!("{}", ident),
                                                                                _ => unimplemented!(),
                                                                        };
-                                                                       gen_types.push_ctx();
-                                                                       assert!(gen_types.learn_generics(&m.sig.generics, types));
-                                                                       write_method_params(w, &m.sig, &ret_type, types, Some(&gen_types), false, true);
+                                                                       let mut meth_gen_types = gen_types.push_ctx();
+                                                                       assert!(meth_gen_types.learn_generics(&m.sig.generics, types));
+                                                                       write_method_params(w, &m.sig, &ret_type, types, Some(&meth_gen_types), false, true);
                                                                        write!(w, " {{\n\t").unwrap();
-                                                                       write_method_var_decl_body(w, &m.sig, "", types, Some(&gen_types), false);
+                                                                       write_method_var_decl_body(w, &m.sig, "", types, Some(&meth_gen_types), false);
                                                                        let mut takes_self = false;
                                                                        let mut takes_mut_self = false;
                                                                        for inp in m.sig.inputs.iter() {
@@ -1010,8 +1022,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                        } else {
                                                                                write!(w, "{}::{}::{}(", types.orig_crate, resolved_path, m.sig.ident).unwrap();
                                                                        }
-                                                                       write_method_call_params(w, &m.sig, "", types, Some(&gen_types), &ret_type, false);
-                                                                       gen_types.pop_ctx();
+                                                                       write_method_call_params(w, &m.sig, "", types, Some(&meth_gen_types), &ret_type, false);
                                                                        writeln!(w, "\n}}\n").unwrap();
                                                                }
                                                        },
@@ -1284,57 +1295,11 @@ fn writeln_fn<'a, 'b, W: std::io::Write>(w: &mut W, f: &'a syn::ItemFn, types: &
 // ********************************
 // *** File/Crate Walking Logic ***
 // ********************************
-/// A public module
-struct ASTModule {
-       pub attrs: Vec<syn::Attribute>,
-       pub items: Vec<syn::Item>,
-       pub submods: Vec<String>,
-}
-/// A struct containing the syn::File AST for each file in the crate.
-struct FullLibraryAST {
-       modules: HashMap<String, ASTModule, NonRandomHash>,
-}
-impl FullLibraryAST {
-       fn load_module(&mut self, module: String, attrs: Vec<syn::Attribute>, mut items: Vec<syn::Item>) {
-               let mut non_mod_items = Vec::with_capacity(items.len());
-               let mut submods = Vec::with_capacity(items.len());
-               for item in items.drain(..) {
-                       match item {
-                               syn::Item::Mod(m) if m.content.is_some() => {
-                                       if export_status(&m.attrs) == ExportStatus::Export {
-                                               if let syn::Visibility::Public(_) = m.vis {
-                                                       let modident = format!("{}", m.ident);
-                                                       let modname = if module != "" {
-                                                               module.clone() + "::" + &modident
-                                                       } else {
-                                                               modident.clone()
-                                                       };
-                                                       self.load_module(modname, m.attrs, m.content.unwrap().1);
-                                                       submods.push(modident);
-                                               } else {
-                                                       non_mod_items.push(syn::Item::Mod(m));
-                                               }
-                                       }
-                               },
-                               syn::Item::Mod(_) => panic!("--pretty=expanded output should never have non-body modules"),
-                               _ => { non_mod_items.push(item); }
-                       }
-               }
-               self.modules.insert(module, ASTModule { attrs, items: non_mod_items, submods });
-       }
-
-       pub fn load_lib(lib: syn::File) -> Self {
-               assert_eq!(export_status(&lib.attrs), ExportStatus::Export);
-               let mut res = Self { modules: HashMap::default() };
-               res.load_module("".to_owned(), lib.attrs, lib.items);
-               res
-       }
-}
 
 /// Do the Real Work of mapping an original file to C-callable wrappers. Creates a new file at
 /// `out_path` and fills it with wrapper structs/functions to allow calling the things in the AST
 /// at `module` from C.
-fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a>, out_dir: &str, orig_crate: &str, header_file: &mut File, cpp_header_file: &mut File) {
+fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &CrateTypes<'a>, out_dir: &str, orig_crate: &str, header_file: &mut File, cpp_header_file: &mut File) {
        for (module, astmod) in libast.modules.iter() {
                let ASTModule { ref attrs, ref items, ref submods } = astmod;
                assert_eq!(export_status(&attrs), ExportStatus::Export);
@@ -1451,11 +1416,7 @@ fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &mut CrateTypes
                                                writeln_fn(&mut out, &f, &mut type_resolver);
                                        }
                                },
-                               syn::Item::Macro(m) => {
-                                       if m.ident.is_none() { // If its not a macro definition
-                                               convert_macro(&mut out, &m.mac.path, &m.mac.tokens, &type_resolver);
-                                       }
-                               },
+                               syn::Item::Macro(_) => {},
                                syn::Item::Verbatim(_) => {},
                                syn::Item::ExternCrate(_) => {},
                                _ => unimplemented!(),
@@ -1518,7 +1479,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a
                                                let trait_path = format!("{}::{}", module, t.ident);
                                                walk_supertraits!(t, None, (
                                                        ("Clone", _) => {
-                                                               crate_types.clonable_types.insert("crate::".to_owned() + &trait_path);
+                                                               crate_types.set_clonable("crate::".to_owned() + &trait_path);
                                                        },
                                                        (_, _) => {}
                                                ) );
@@ -1587,7 +1548,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a
                                                if let Some(trait_path) = i.trait_.as_ref() {
                                                        if path_matches_nongeneric(&trait_path.1, &["core", "clone", "Clone"]) {
                                                                if let Some(full_path) = import_resolver.maybe_resolve_path(&p.path, None) {
-                                                                       crate_types.clonable_types.insert("crate::".to_owned() + &full_path);
+                                                                       crate_types.set_clonable("crate::".to_owned() + &full_path);
                                                                }
                                                        }
                                                        if let Some(tp) = import_resolver.maybe_resolve_path(&trait_path.1, None) {
@@ -1645,18 +1606,15 @@ fn main() {
 
        // ...then walk the ASTs tracking what types we will map, and how, so that we can resolve them
        // when parsing other file ASTs...
-       let mut libtypes = CrateTypes { traits: HashMap::new(), opaques: HashMap::new(), mirrored_enums: HashMap::new(),
-               type_aliases: HashMap::new(), reverse_alias_map: HashMap::new(), templates_defined: HashMap::default(),
-               template_file: &mut derived_templates,
-               clonable_types: HashSet::new(), trait_impls: HashMap::new() };
+       let mut libtypes = CrateTypes::new(&mut derived_templates, &libast);
        walk_ast(&libast, &mut libtypes);
 
        // ... finally, do the actual file conversion/mapping, writing out types as we go.
-       convert_file(&libast, &mut libtypes, &args[1], &args[2], &mut header_file, &mut cpp_header_file);
+       convert_file(&libast, &libtypes, &args[1], &args[2], &mut header_file, &mut cpp_header_file);
 
        // For container templates which we created while walking the crate, make sure we add C++
        // mapped types so that C++ users can utilize the auto-destructors available.
-       for (ty, has_destructor) in libtypes.templates_defined.iter() {
+       for (ty, has_destructor) in libtypes.templates_defined.borrow().iter() {
                write_cpp_wrapper(&mut cpp_header_file, ty, *has_destructor);
        }
        writeln!(cpp_header_file, "}}").unwrap();
index 10f83e5079d20051b568f2af3612eaf071f4907f..92da8727929bd1f0ef43b245fc2895b05bc95aa0 100644 (file)
@@ -6,6 +6,7 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
+use std::cell::RefCell;
 use std::collections::{HashMap, HashSet};
 use std::fs::File;
 use std::io::Write;
@@ -159,23 +160,21 @@ pub fn is_enum_opaque(e: &syn::ItemEnum) -> bool {
 /// It maps both direct types as well as Deref<Target = X>, mapping them via the provided
 /// TypeResolver's resolve_path function (ie traits map to the concrete jump table, structs to the
 /// concrete C container struct, etc).
-pub struct GenericTypes<'a> {
-       typed_generics: Vec<HashMap<&'a syn::Ident, (String, Option<&'a syn::Path>)>>,
+#[must_use]
+pub struct GenericTypes<'a, 'b> {
+       parent: Option<&'b GenericTypes<'b, 'b>>,
+       typed_generics: HashMap<&'a syn::Ident, (String, Option<&'a syn::Path>)>,
 }
-impl<'a> GenericTypes<'a> {
+impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
        pub fn new() -> Self {
-               Self { typed_generics: vec![HashMap::new()], }
+               Self { parent: None, typed_generics: HashMap::new(), }
        }
 
        /// push a new context onto the stack, allowing for a new set of generics to be learned which
        /// will override any lower contexts, but which will still fall back to resoltion via lower
        /// contexts.
-       pub fn push_ctx(&mut self) {
-               self.typed_generics.push(HashMap::new());
-       }
-       /// pop the latest context off the stack.
-       pub fn pop_ctx(&mut self) {
-               self.typed_generics.pop();
+       pub fn push_ctx<'c>(&'c self) -> GenericTypes<'a, 'c> {
+               GenericTypes { parent: Some(self), typed_generics: HashMap::new(), }
        }
 
        /// Learn the generics in generics in the current context, given a TypeResolver.
@@ -201,7 +200,7 @@ impl<'a> GenericTypes<'a> {
                                                                        path = "crate::".to_string() + &path;
                                                                        Some(&trait_bound.path)
                                                                } else { None };
-                                                               self.typed_generics.last_mut().unwrap().insert(&type_param.ident, (path, new_ident));
+                                                               self.typed_generics.insert(&type_param.ident, (path, new_ident));
                                                        } else { return false; }
                                                }
                                        }
@@ -217,7 +216,7 @@ impl<'a> GenericTypes<'a> {
                                                if p.qself.is_some() { return false; }
                                                if p.path.leading_colon.is_some() { return false; }
                                                let mut p_iter = p.path.segments.iter();
-                                               if let Some(gen) = self.typed_generics.last_mut().unwrap().get_mut(&p_iter.next().unwrap().ident) {
+                                               if let Some(gen) = self.typed_generics.get_mut(&p_iter.next().unwrap().ident) {
                                                        if gen.0 != "std::ops::Deref" { return false; }
                                                        if &format!("{}", p_iter.next().unwrap().ident) != "Target" { return false; }
 
@@ -236,7 +235,7 @@ impl<'a> GenericTypes<'a> {
                                }
                        }
                }
-               for (_, (_, ident)) in self.typed_generics.last().unwrap().iter() {
+               for (_, (_, ident)) in self.typed_generics.iter() {
                        if ident.is_none() { return false; }
                }
                true
@@ -262,7 +261,7 @@ impl<'a> GenericTypes<'a> {
                                                                        path = "crate::".to_string() + &path;
                                                                        Some(&tr.path)
                                                                } else { None };
-                                                               self.typed_generics.last_mut().unwrap().insert(&t.ident, (path, new_ident));
+                                                               self.typed_generics.insert(&t.ident, (path, new_ident));
                                                        } else { unimplemented!(); }
                                                },
                                                _ => unimplemented!(),
@@ -276,21 +275,21 @@ impl<'a> GenericTypes<'a> {
 
        /// Attempt to resolve an Ident as a generic parameter and return the full path.
        pub fn maybe_resolve_ident<'b>(&'b self, ident: &syn::Ident) -> Option<&'b String> {
-               for gen in self.typed_generics.iter().rev() {
-                       if let Some(res) = gen.get(ident).map(|(a, _)| a) {
-                               return Some(res);
-                       }
+               if let Some(res) = self.typed_generics.get(ident).map(|(a, _)| a) {
+                       return Some(res);
+               }
+               if let Some(parent) = self.parent {
+                       parent.maybe_resolve_ident(ident)
+               } else {
+                       None
                }
-               None
        }
        /// Attempt to resolve a Path as a generic parameter and return the full path. as both a string
        /// and syn::Path.
        pub fn maybe_resolve_path<'b>(&'b self, path: &syn::Path) -> Option<(&'b String, &'a syn::Path)> {
                if let Some(ident) = path.get_ident() {
-                       for gen in self.typed_generics.iter().rev() {
-                               if let Some(res) = gen.get(ident).map(|(a, b)| (a, b.unwrap())) {
-                                       return Some(res);
-                               }
+                       if let Some(res) = self.typed_generics.get(ident).map(|(a, b)| (a, b.unwrap())) {
+                               return Some(res);
                        }
                } else {
                        // Associated types are usually specified as "Self::Generic", so we check for that
@@ -298,14 +297,16 @@ impl<'a> GenericTypes<'a> {
                        let mut it = path.segments.iter();
                        if path.segments.len() == 2 && format!("{}", it.next().unwrap().ident) == "Self" {
                                let ident = &it.next().unwrap().ident;
-                               for gen in self.typed_generics.iter().rev() {
-                                       if let Some(res) = gen.get(ident).map(|(a, b)| (a, b.unwrap())) {
-                                               return Some(res);
-                                       }
+                               if let Some(res) = self.typed_generics.get(ident).map(|(a, b)| (a, b.unwrap())) {
+                                       return Some(res);
                                }
                        }
                }
-               None
+               if let Some(parent) = self.parent {
+                       parent.maybe_resolve_path(path)
+               } else {
+                       None
+               }
        }
 }
 
@@ -539,6 +540,53 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
 #[allow(deprecated)]
 pub type NonRandomHash = hash::BuildHasherDefault<hash::SipHasher>;
 
+/// A public module
+pub struct ASTModule {
+       pub attrs: Vec<syn::Attribute>,
+       pub items: Vec<syn::Item>,
+       pub submods: Vec<String>,
+}
+/// A struct containing the syn::File AST for each file in the crate.
+pub struct FullLibraryAST {
+       pub modules: HashMap<String, ASTModule, NonRandomHash>,
+}
+impl FullLibraryAST {
+       fn load_module(&mut self, module: String, attrs: Vec<syn::Attribute>, mut items: Vec<syn::Item>) {
+               let mut non_mod_items = Vec::with_capacity(items.len());
+               let mut submods = Vec::with_capacity(items.len());
+               for item in items.drain(..) {
+                       match item {
+                               syn::Item::Mod(m) if m.content.is_some() => {
+                                       if export_status(&m.attrs) == ExportStatus::Export {
+                                               if let syn::Visibility::Public(_) = m.vis {
+                                                       let modident = format!("{}", m.ident);
+                                                       let modname = if module != "" {
+                                                               module.clone() + "::" + &modident
+                                                       } else {
+                                                               modident.clone()
+                                                       };
+                                                       self.load_module(modname, m.attrs, m.content.unwrap().1);
+                                                       submods.push(modident);
+                                               } else {
+                                                       non_mod_items.push(syn::Item::Mod(m));
+                                               }
+                                       }
+                               },
+                               syn::Item::Mod(_) => panic!("--pretty=expanded output should never have non-body modules"),
+                               _ => { non_mod_items.push(item); }
+                       }
+               }
+               self.modules.insert(module, ASTModule { attrs, items: non_mod_items, submods });
+       }
+
+       pub fn load_lib(lib: syn::File) -> Self {
+               assert_eq!(export_status(&lib.attrs), ExportStatus::Export);
+               let mut res = Self { modules: HashMap::default() };
+               res.load_module("".to_owned(), lib.attrs, lib.items);
+               res
+       }
+}
+
 /// Top-level struct tracking everything which has been defined while walking the crate.
 pub struct CrateTypes<'a> {
        /// This may contain structs or enums, but only when either is mapped as
@@ -556,14 +604,38 @@ pub struct CrateTypes<'a> {
        /// exists.
        ///
        /// This is used at the end of processing to make C++ wrapper classes
-       pub templates_defined: HashMap<String, bool, NonRandomHash>,
+       pub templates_defined: RefCell<HashMap<String, bool, NonRandomHash>>,
        /// The output file for any created template container types, written to as we find new
        /// template containers which need to be defined.
-       pub template_file: &'a mut File,
+       template_file: RefCell<&'a mut File>,
        /// Set of containers which are clonable
-       pub clonable_types: HashSet<String>,
+       clonable_types: RefCell<HashSet<String>>,
        /// Key impls Value
        pub trait_impls: HashMap<String, Vec<String>>,
+       /// The full set of modules in the crate(s)
+       pub lib_ast: &'a FullLibraryAST,
+}
+
+impl<'a> CrateTypes<'a> {
+       pub fn new(template_file: &'a mut File, libast: &'a FullLibraryAST) -> Self {
+               CrateTypes {
+                       opaques: HashMap::new(), mirrored_enums: HashMap::new(), traits: HashMap::new(),
+                       type_aliases: HashMap::new(), reverse_alias_map: HashMap::new(),
+                       templates_defined: RefCell::new(HashMap::default()),
+                       clonable_types: RefCell::new(HashSet::new()), trait_impls: HashMap::new(),
+                       template_file: RefCell::new(template_file), lib_ast: &libast,
+               }
+       }
+       pub fn set_clonable(&self, object: String) {
+               self.clonable_types.borrow_mut().insert(object);
+       }
+       pub fn is_clonable(&self, object: &str) -> bool {
+               self.clonable_types.borrow().contains(object)
+       }
+       pub fn write_new_template(&self, mangled_container: String, has_destructor: bool, created_container: &[u8]) {
+               self.template_file.borrow_mut().write(created_container).unwrap();
+               self.templates_defined.borrow_mut().insert(mangled_container, has_destructor);
+       }
 }
 
 /// A struct which tracks resolving rust types into C-mapped equivalents, exists for one specific
@@ -571,7 +643,7 @@ pub struct CrateTypes<'a> {
 pub struct TypeResolver<'mod_lifetime, 'crate_lft: 'mod_lifetime> {
        pub orig_crate: &'mod_lifetime str,
        pub module_path: &'mod_lifetime str,
-       pub crate_types: &'mod_lifetime mut CrateTypes<'crate_lft>,
+       pub crate_types: &'mod_lifetime CrateTypes<'crate_lft>,
        types: ImportResolver<'mod_lifetime, 'crate_lft>,
 }
 
@@ -601,7 +673,7 @@ enum ContainerPrefixLocation {
 }
 
 impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
-       pub fn new(orig_crate: &'a str, module_path: &'a str, types: ImportResolver<'a, 'c>, crate_types: &'a mut CrateTypes<'c>) -> Self {
+       pub fn new(orig_crate: &'a str, module_path: &'a str, types: ImportResolver<'a, 'c>, crate_types: &'a CrateTypes<'c>) -> Self {
                Self { orig_crate, module_path, types, crate_types }
        }
 
@@ -636,7 +708,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                }
        }
        pub fn is_clonable(&self, ty: &str) -> bool {
-               if self.crate_types.clonable_types.contains(ty) { return true; }
+               if self.crate_types.is_clonable(ty) { return true; }
                if self.is_primitive(ty) { return true; }
                match ty {
                        "()" => true,
@@ -1932,7 +2004,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
        // *** C Container Type Equivalent and alias Printing ***
        // ******************************************************
 
-       fn write_template_generics<'b, W: std::io::Write>(&mut self, w: &mut W, args: &mut dyn Iterator<Item=&'b syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) -> bool {
+       fn write_template_generics<'b, W: std::io::Write>(&self, w: &mut W, args: &mut dyn Iterator<Item=&'b syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) -> bool {
                for (idx, t) in args.enumerate() {
                        if idx != 0 {
                                write!(w, ", ").unwrap();
@@ -1966,8 +2038,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                }
                true
        }
-       fn check_create_container(&mut self, mangled_container: String, container_type: &str, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) -> bool {
-               if !self.crate_types.templates_defined.get(&mangled_container).is_some() {
+       fn check_create_container(&self, mangled_container: String, container_type: &str, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, is_ref: bool) -> bool {
+               if !self.crate_types.templates_defined.borrow().get(&mangled_container).is_some() {
                        let mut created_container: Vec<u8> = Vec::new();
 
                        if container_type == "Result" {
@@ -1998,7 +2070,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                let is_clonable = self.is_clonable(&ok_str) && self.is_clonable(&err_str);
                                write_result_block(&mut created_container, &mangled_container, &ok_str, &err_str, is_clonable);
                                if is_clonable {
-                                       self.crate_types.clonable_types.insert(Self::generated_container_path().to_owned() + "::" + &mangled_container);
+                                       self.crate_types.set_clonable(Self::generated_container_path().to_owned() + "::" + &mangled_container);
                                }
                        } else if container_type == "Vec" {
                                let mut a_ty: Vec<u8> = Vec::new();
@@ -2007,7 +2079,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                let is_clonable = self.is_clonable(&ty);
                                write_vec_block(&mut created_container, &mangled_container, &ty, is_clonable);
                                if is_clonable {
-                                       self.crate_types.clonable_types.insert(Self::generated_container_path().to_owned() + "::" + &mangled_container);
+                                       self.crate_types.set_clonable(Self::generated_container_path().to_owned() + "::" + &mangled_container);
                                }
                        } else if container_type.ends_with("Tuple") {
                                let mut tuple_args = Vec::new();
@@ -2023,7 +2095,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                }
                                write_tuple_block(&mut created_container, &mangled_container, &tuple_args, is_clonable);
                                if is_clonable {
-                                       self.crate_types.clonable_types.insert(Self::generated_container_path().to_owned() + "::" + &mangled_container);
+                                       self.crate_types.set_clonable(Self::generated_container_path().to_owned() + "::" + &mangled_container);
                                }
                        } else if container_type == "Option" {
                                let mut a_ty: Vec<u8> = Vec::new();
@@ -2032,14 +2104,12 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                let is_clonable = self.is_clonable(&ty);
                                write_option_block(&mut created_container, &mangled_container, &ty, is_clonable);
                                if is_clonable {
-                                       self.crate_types.clonable_types.insert(Self::generated_container_path().to_owned() + "::" + &mangled_container);
+                                       self.crate_types.set_clonable(Self::generated_container_path().to_owned() + "::" + &mangled_container);
                                }
                        } else {
                                unreachable!();
                        }
-                       self.crate_types.templates_defined.insert(mangled_container.clone(), true);
-
-                       self.crate_types.template_file.write(&created_container).unwrap();
+                       self.crate_types.write_new_template(mangled_container.clone(), true, &created_container);
                }
                true
        }
@@ -2049,7 +2119,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                } else { unimplemented!(); }
        }
        fn write_c_mangled_container_path_intern<W: std::io::Write>
-                       (&mut self, w: &mut W, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool, in_type: bool) -> bool {
+                       (&self, w: &mut W, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool, in_type: bool) -> bool {
                let mut mangled_type: Vec<u8> = Vec::new();
                if !self.is_transparent_container(ident, is_ref, args.iter().map(|a| *a)) {
                        write!(w, "C{}_", ident).unwrap();
@@ -2161,7 +2231,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                // Make sure the type is actually defined:
                self.check_create_container(String::from_utf8(mangled_type).unwrap(), ident, args, generics, is_ref)
        }
-       fn write_c_mangled_container_path<W: std::io::Write>(&mut self, w: &mut W, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
+       fn write_c_mangled_container_path<W: std::io::Write>(&self, w: &mut W, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, ident: &str, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
                if !self.is_transparent_container(ident, is_ref, args.iter().map(|a| *a)) {
                        write!(w, "{}::", Self::generated_container_path()).unwrap();
                }
@@ -2204,7 +2274,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        false
                }
        }
-       fn write_c_type_intern<W: std::io::Write>(&mut self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
+       fn write_c_type_intern<W: std::io::Write>(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool) -> bool {
                match t {
                        syn::Type::Path(p) => {
                                if p.qself.is_some() {
@@ -2295,14 +2365,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        _ => false,
                }
        }
-       pub fn write_c_type<W: std::io::Write>(&mut self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, ptr_for_ref: bool) {
+       pub fn write_c_type<W: std::io::Write>(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, ptr_for_ref: bool) {
                assert!(self.write_c_type_intern(w, t, generics, false, false, ptr_for_ref));
        }
-       pub fn understood_c_path(&mut self, p: &syn::Path) -> bool {
+       pub fn understood_c_path(&self, p: &syn::Path) -> bool {
                if p.leading_colon.is_some() { return false; }
                self.write_c_path_intern(&mut std::io::sink(), p, None, false, false, false)
        }
-       pub fn understood_c_type(&mut self, t: &syn::Type, generics: Option<&GenericTypes>) -> bool {
+       pub fn understood_c_type(&self, t: &syn::Type, generics: Option<&GenericTypes>) -> bool {
                self.write_c_type_intern(&mut std::io::sink(), t, generics, false, false, false)
        }
 }
index e8e556b58afa352488e10954613ea721f6db8272..788cff11544be6424a908d1e96209517ce681a26 100644 (file)
@@ -18,11 +18,11 @@ crate-type = ["staticlib"
 bitcoin = "0.26"
 secp256k1 = { version = "0.20.1", features = ["global-context-less-secure"] }
 # Note that the following line is matched by genbindings to update the path
-lightning = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "6fcac8bc65ed6d372e0b8c367e9934c754f99ff3", features = ["allow_wallclock_use"] }
+lightning = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "8088e4ba1505c026ac91f8c1489fb7d53d6b656e", features = ["allow_wallclock_use"] }
 
 [patch.crates-io]
 # Rust-Secp256k1 PR 279. Should be dropped once merged.
-secp256k1 = { git = 'https://github.com/TheBlueMatt/rust-secp256k1', rev = '15a0d4195a20355f6b1e8f54c84eba56abc15cbd' }
+secp256k1 = { git = 'https://github.com/TheBlueMatt/rust-secp256k1', rev = '50bf9e48ca0f0d267c41e729520a2673ecfaa84f' }
 
 # Always force panic=abort, further options are set in the genbindings.sh build script
 [profile.dev]
index 230e33436848b6e2a603ba81194d1e686ae92243..222e29e69619efa8dae9ca88026574545e8f300f 100644 (file)
@@ -373,8 +373,8 @@ int main() {
 
                // Demo getting a channel key and check that its returning real pubkeys:
                LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
-               chan_signer1->set_pubkeys(&chan_signer1); // Make sure pubkeys is defined
-               LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->pubkeys);
+               chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
+               LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
                assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
 
                // Instantiate classes for node 2:
@@ -437,10 +437,10 @@ int main() {
                                assert(events->data[0].funding_generation_ready.channel_value_satoshis == 40000);
                                assert(events->data[0].funding_generation_ready.output_script.datalen == 34);
                                assert(!memcmp(events->data[0].funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
-                               LDKThirtyTwoBytes txid;
-                               for (int i = 0; i < 32; i++) { txid.data[i] = channel_open_txid[31-i]; }
-                               LDK::OutPoint outp = OutPoint_new(txid, 0);
-                               ChannelManager_funding_transaction_generated(&cm1, &events->data[0].funding_generation_ready.temporary_channel_id.data, std::move(outp));
+                               LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
+
+                               LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &events->data[0].funding_generation_ready.temporary_channel_id.data, funding_transaction);
+                               assert(fund_res->result_ok);
                                break;
                        }
                        std::this_thread::yield();
@@ -448,14 +448,9 @@ int main() {
 
                // We observe when the funding signed messages have been exchanged by
                // waiting for two monitors to be registered.
+               assert(num_txs_broadcasted == 0);
                PeerManager_process_events(&net1);
-               while (true) {
-                       LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
-                       if (events->datalen == 1) {
-                               assert(events->data[0].tag == LDKEvent_FundingBroadcastSafe);
-                               assert(events->data[0].funding_broadcast_safe.user_channel_id == 42);
-                               break;
-                       }
+               while (num_txs_broadcasted != 1) {
                        std::this_thread::yield();
                }
 
index bdeb29858d5c9e60954c4eaebab3f4e1e0909a5f..168bc7cb02825375a7cf19227694bf7b9f9e7ea6 100644 (file)
@@ -3201,12 +3201,6 @@ typedef enum LDKEvent_Tag {
     * counterparty can steal your funds!
     */
    LDKEvent_FundingGenerationReady,
-   /**
-    * Used to indicate that the client may now broadcast the funding transaction it created for a
-    * channel. Broadcasting such a transaction prior to this event may lead to our counterparty
-    * trivially stealing all funds in the funding transaction!
-    */
-   LDKEvent_FundingBroadcastSafe,
    /**
     * Indicates we've received money! Just gotta dig out that payment preimage and feed it to
     * ChannelManager::claim_funds to get it....
@@ -3272,18 +3266,6 @@ typedef struct LDKEvent_LDKFundingGenerationReady_Body {
    uint64_t user_channel_id;
 } LDKEvent_LDKFundingGenerationReady_Body;
 
-typedef struct LDKEvent_LDKFundingBroadcastSafe_Body {
-   /**
-    * The output, which was passed to ChannelManager::funding_transaction_generated, which is
-    * now safe to broadcast.
-    */
-   struct LDKOutPoint funding_txo;
-   /**
-    * The value passed in to ChannelManager::create_channel
-    */
-   uint64_t user_channel_id;
-} LDKEvent_LDKFundingBroadcastSafe_Body;
-
 typedef struct LDKEvent_LDKPaymentReceived_Body {
    /**
     * The hash for which the preimage should be handed to the ChannelManager.
@@ -3352,7 +3334,6 @@ typedef struct MUST_USE_STRUCT LDKEvent {
    LDKEvent_Tag tag;
    union {
       LDKEvent_LDKFundingGenerationReady_Body funding_generation_ready;
-      LDKEvent_LDKFundingBroadcastSafe_Body funding_broadcast_safe;
       LDKEvent_LDKPaymentReceived_Body payment_received;
       LDKEvent_LDKPaymentSent_Body payment_sent;
       LDKEvent_LDKPaymentFailed_Body payment_failed;
@@ -3820,7 +3801,7 @@ typedef struct MUST_USE_STRUCT LDKUnsignedChannelAnnouncement {
  * to act, as liveness and breach reply correctness are always going to be hard requirements
  * of LN security model, orthogonal of key management issues.
  */
-typedef struct LDKSign {
+typedef struct LDKBaseSign {
    /**
     * An opaque pointer which is passed to your function implementations as an argument.
     * This has no meaning in the LDK, and can be NULL or any other value.
@@ -3852,7 +3833,7 @@ typedef struct LDKSign {
     * Note that this takes a pointer to this object, not the this_ptr like other methods do
     * This function pointer may be NULL if pubkeys is filled in when this object is created and never needs updating.
     */
-   void (*set_pubkeys)(const struct LDKSign*NONNULL_PTR );
+   void (*set_pubkeys)(const struct LDKBaseSign*NONNULL_PTR );
    /**
     * Gets an arbitrary identifier describing the set of keys which are provided back to you in
     * some SpendableOutputDescriptor types. This should be sufficient to identify this
@@ -3950,15 +3931,44 @@ typedef struct LDKSign {
     */
    void (*ready_channel)(void *this_arg, const struct LDKChannelTransactionParameters *NONNULL_PTR channel_parameters);
    /**
-    * Creates a copy of the object pointed to by this_arg, for a copy of this Sign.
-    * Note that the ultimate copy of the Sign will have all function pointers the same as the original.
-    * May be NULL if no action needs to be taken, the this_arg pointer will be copied into the new Sign.
+    * Frees any resources associated with this object given its this_arg pointer.
+    * Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed.
     */
-   void *(*clone)(const void *this_arg);
+   void (*free)(void *this_arg);
+} LDKBaseSign;
+
+/**
+ * A cloneable signer.
+ *
+ * Although we require signers to be cloneable, it may be useful for developers to be able to use
+ * signers in an un-sized way, for example as `dyn BaseSign`. Therefore we separate the Clone trait,
+ * which implies Sized, into this derived trait.
+ */
+typedef struct LDKSign {
+   /**
+    * An opaque pointer which is passed to your function implementations as an argument.
+    * This has no meaning in the LDK, and can be NULL or any other value.
+    */
+   void *this_arg;
+   /**
+    * Implementation of BaseSign for this object.
+    */
+   struct LDKBaseSign BaseSign;
+   /**
+    * Creates a copy of the BaseSign, for a copy of this Sign.
+    * Because BaseSign doesn't natively support copying itself, you have to provide a full copy implementation here.
+    */
+   struct LDKBaseSign (*BaseSign_clone)(const struct LDKBaseSign *NONNULL_PTR orig_BaseSign);
    /**
     * Serialize the object into a byte array
     */
    struct LDKCVec_u8Z (*write)(const void *this_arg);
+   /**
+    * Creates a copy of the object pointed to by this_arg, for a copy of this Sign.
+    * Note that the ultimate copy of the Sign will have all function pointers the same as the original.
+    * May be NULL if no action needs to be taken, the this_arg pointer will be copied into the new Sign.
+    */
+   void *(*clone)(const void *this_arg);
    /**
     * Frees any resources associated with this object given its this_arg pointer.
     * Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed.
@@ -10531,6 +10541,11 @@ struct LDKCVec_u8Z SpendableOutputDescriptor_write(const struct LDKSpendableOutp
  */
 struct LDKCResult_SpendableOutputDescriptorDecodeErrorZ SpendableOutputDescriptor_read(struct LDKu8slice ser);
 
+/**
+ * Calls the free function if one is set
+ */
+void BaseSign_free(struct LDKBaseSign this_ptr);
+
 /**
  * Creates a copy of a Sign
  */
@@ -10682,6 +10697,12 @@ MUST_USE_RES struct LDKCResult_CVec_CVec_u8ZZNoneZ InMemorySigner_sign_counterpa
  */
 MUST_USE_RES struct LDKCResult_CVec_CVec_u8ZZNoneZ InMemorySigner_sign_dynamic_p2wsh_input(const struct LDKInMemorySigner *NONNULL_PTR this_arg, struct LDKTransaction spend_tx, uintptr_t input_idx, const struct LDKDelayedPaymentOutputDescriptor *NONNULL_PTR descriptor);
 
+/**
+ * Constructs a new BaseSign which calls the relevant methods on this_arg.
+ * This copies the `inner` pointer in this_arg and thus the returned BaseSign must be freed before this_arg is
+ */
+struct LDKBaseSign InMemorySigner_as_BaseSign(const struct LDKInMemorySigner *NONNULL_PTR this_arg);
+
 /**
  * Constructs a new Sign which calls the relevant methods on this_arg.
  * This copies the `inner` pointer in this_arg and thus the returned Sign must be freed before this_arg is
@@ -10962,10 +10983,11 @@ MUST_USE_RES struct LDKChannelManager ChannelManager_new(struct LDKFeeEstimator
 /**
  * Creates a new outbound channel to the given remote node and with the given value.
  *
- * user_id will be provided back as user_channel_id in FundingGenerationReady and
- * FundingBroadcastSafe events to allow tracking of which events correspond with which
- * create_channel call. Note that user_channel_id defaults to 0 for inbound channels, so you
- * may wish to avoid using 0 for user_id here.
+ * user_id will be provided back as user_channel_id in FundingGenerationReady events to allow
+ * tracking of which events correspond with which create_channel call. Note that the
+ * user_channel_id defaults to 0 for inbound channels, so you may wish to avoid using 0 for
+ * user_id here. user_id has no meaning inside of LDK, it is simply copied to events and
+ * otherwise ignored.
  *
  * If successful, will generate a SendOpenChannel message event, so you should probably poll
  * PeerManager::process_events afterwards.
@@ -11057,15 +11079,24 @@ MUST_USE_RES struct LDKCResult_NonePaymentSendFailureZ ChannelManager_send_payme
 /**
  * Call this upon creation of a funding transaction for the given channel.
  *
- * Note that ALL inputs in the transaction pointed to by funding_txo MUST spend SegWit outputs
- * or your counterparty can steal your funds!
+ * Returns an [`APIError::APIMisuseError`] if the funding_transaction spent non-SegWit outputs
+ * or if no output was found which matches the parameters in [`Event::FundingGenerationReady`].
  *
  * Panics if a funding transaction has already been provided for this channel.
  *
- * May panic if the funding_txo is duplicative with some other channel (note that this should
- * be trivially prevented by using unique funding transaction keys per-channel).
+ * May panic if the output found in the funding transaction is duplicative with some other
+ * channel (note that this should be trivially prevented by using unique funding transaction
+ * keys per-channel).
+ *
+ * Do NOT broadcast the funding transaction yourself. When we have safely received our
+ * counterparty's signature the funding transaction will automatically be broadcast via the
+ * [`BroadcasterInterface`] provided when this `ChannelManager` was constructed.
+ *
+ * Note that this includes RBF or similar transaction replacement strategies - lightning does
+ * not currently support replacing a funding transaction on an existing channel. Instead,
+ * create a new channel with a conflicting funding transaction.
  */
-void ChannelManager_funding_transaction_generated(const struct LDKChannelManager *NONNULL_PTR this_arg, const uint8_t (*temporary_channel_id)[32], struct LDKOutPoint funding_txo);
+MUST_USE_RES struct LDKCResult_NoneAPIErrorZ ChannelManager_funding_transaction_generated(const struct LDKChannelManager *NONNULL_PTR this_arg, const uint8_t (*temporary_channel_id)[32], struct LDKTransaction funding_transaction);
 
 /**
  * Generates a signed node_announcement from the given arguments and creates a
@@ -11179,17 +11210,42 @@ struct LDKEventsProvider ChannelManager_as_EventsProvider(const struct LDKChanne
 struct LDKListen ChannelManager_as_Listen(const struct LDKChannelManager *NONNULL_PTR this_arg);
 
 /**
- * Updates channel state based on transactions seen in a connected block.
+ * Updates channel state to take note of transactions which were confirmed in the given block
+ * at the given height.
+ *
+ * Note that you must still call (or have called) [`update_best_block`] with the block
+ * information which is included here.
+ *
+ * This method may be called before or after [`update_best_block`] for a given block's
+ * transaction data and may be called multiple times with additional transaction data for a
+ * given block.
+ *
+ * This method may be called for a previous block after an [`update_best_block`] call has
+ * been made for a later block, however it must *not* be called with transaction data from a
+ * block which is no longer in the best chain (ie where [`update_best_block`] has already
+ * been informed about a blockchain reorganization which no longer includes the block which
+ * corresponds to `header`).
+ *
+ * [`update_best_block`]: `Self::update_best_block`
  */
-void ChannelManager_block_connected(const struct LDKChannelManager *NONNULL_PTR this_arg, const uint8_t (*header)[80], struct LDKCVec_C2Tuple_usizeTransactionZZ txdata, uint32_t height);
+void ChannelManager_transactions_confirmed(const struct LDKChannelManager *NONNULL_PTR this_arg, const uint8_t (*header)[80], uint32_t height, struct LDKCVec_C2Tuple_usizeTransactionZZ txdata);
 
 /**
- * Updates channel state based on a disconnected block.
+ * Updates channel state with the current best blockchain tip. You should attempt to call this
+ * quickly after a new block becomes available, however if multiple new blocks become
+ * available at the same time, only a single `update_best_block()` call needs to be made.
+ *
+ * This method should also be called immediately after any block disconnections, once at the
+ * reorganization fork point, and once with the new chain tip. Calling this method at the
+ * blockchain reorganization fork point ensures we learn when a funding transaction which was
+ * previously confirmed is reorganized out of the blockchain, ensuring we do not continue to
+ * accept payments which cannot be enforced on-chain.
  *
- * If necessary, the channel may be force-closed without letting the counterparty participate
- * in the shutdown.
+ * In both the block-connection and block-disconnection case, this method may be called either
+ * once per block connected or disconnected, or simply at the fork point and new tip(s),
+ * skipping any intermediary blocks.
  */
-void ChannelManager_block_disconnected(const struct LDKChannelManager *NONNULL_PTR this_arg, const uint8_t (*header)[80]);
+void ChannelManager_update_best_block(const struct LDKChannelManager *NONNULL_PTR this_arg, const uint8_t (*header)[80], uint32_t height);
 
 /**
  * Blocks until ChannelManager needs to be persisted or a timeout is reached. It returns a bool
index b73d943d74b84440f0c60028e79ad5b4ad471377..ef43273fc47b994a07ff2d599ec5909dc50f0b5c 100644 (file)
@@ -971,6 +971,21 @@ public:
        const LDKSpendableOutputDescriptor* operator &() const { return &self; }
        const LDKSpendableOutputDescriptor* operator ->() const { return &self; }
 };
+class BaseSign {
+private:
+       LDKBaseSign self;
+public:
+       BaseSign(const BaseSign&) = delete;
+       BaseSign(BaseSign&& o) : self(o.self) { memset(&o, 0, sizeof(BaseSign)); }
+       BaseSign(LDKBaseSign&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKBaseSign)); }
+       operator LDKBaseSign() && { LDKBaseSign res = self; memset(&self, 0, sizeof(LDKBaseSign)); return res; }
+       ~BaseSign() { BaseSign_free(self); }
+       BaseSign& operator=(BaseSign&& o) { BaseSign_free(self); self = o.self; memset(&o, 0, sizeof(BaseSign)); return *this; }
+       LDKBaseSign* operator &() { return &self; }
+       LDKBaseSign* operator ->() { return &self; }
+       const LDKBaseSign* operator &() const { return &self; }
+       const LDKBaseSign* operator ->() const { return &self; }
+};
 class Sign {
 private:
        LDKSign self;
index aecf627c0f782427a0fdcc875fd7b6649f49443d..34db4a609ad263f537fd145cc5e3a70b0e99063d 100644 (file)
@@ -99,8 +99,8 @@ struct nativeDelayedPaymentOutputDescriptorOpaque;
 typedef struct nativeDelayedPaymentOutputDescriptorOpaque LDKnativeDelayedPaymentOutputDescriptor;
 struct nativeStaticPaymentOutputDescriptorOpaque;
 typedef struct nativeStaticPaymentOutputDescriptorOpaque LDKnativeStaticPaymentOutputDescriptor;
-struct LDKSign;
-typedef struct LDKSign LDKSign;
+struct LDKBaseSign;
+typedef struct LDKBaseSign LDKBaseSign;
 struct nativeInMemorySignerOpaque;
 typedef struct nativeInMemorySignerOpaque LDKnativeInMemorySigner;
 struct nativeKeysManagerOpaque;
index daa76b78ace8c752ecb57fe92c2e97455dae6be0..5c50e533d5c1caa401d080564e0391fb8b32bd65 100644 (file)
@@ -481,7 +481,7 @@ pub extern "C" fn SpendableOutputDescriptor_read(ser: crate::c_types::u8slice) -
 /// to act, as liveness and breach reply correctness are always going to be hard requirements
 /// of LN security model, orthogonal of key management issues.
 #[repr(C)]
-pub struct Sign {
+pub struct BaseSign {
        /// An opaque pointer which is passed to your function implementations as an argument.
        /// This has no meaning in the LDK, and can be NULL or any other value.
        pub this_arg: *mut c_void,
@@ -505,7 +505,7 @@ pub struct Sign {
        /// Fill in the pubkeys field as a reference to it will be given to Rust after this returns
        /// Note that this takes a pointer to this object, not the this_ptr like other methods do
        /// This function pointer may be NULL if pubkeys is filled in when this object is created and never needs updating.
-       pub set_pubkeys: Option<extern "C" fn(&Sign)>,
+       pub set_pubkeys: Option<extern "C" fn(&BaseSign)>,
        /// Gets an arbitrary identifier describing the set of keys which are provided back to you in
        /// some SpendableOutputDescriptor types. This should be sufficient to identify this
        /// Sign object uniquely and lookup or re-derive its keys.
@@ -593,54 +593,15 @@ pub struct Sign {
        ///
        /// Will be called before any signatures are applied.
        pub ready_channel: extern "C" fn (this_arg: *mut c_void, channel_parameters: &crate::ln::chan_utils::ChannelTransactionParameters),
-       /// Creates a copy of the object pointed to by this_arg, for a copy of this Sign.
-       /// Note that the ultimate copy of the Sign will have all function pointers the same as the original.
-       /// May be NULL if no action needs to be taken, the this_arg pointer will be copied into the new Sign.
-       pub clone: Option<extern "C" fn (this_arg: *const c_void) -> *mut c_void>,
-       /// Serialize the object into a byte array
-       pub write: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_u8Z,
        /// Frees any resources associated with this object given its this_arg pointer.
        /// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed.
        pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
 }
-unsafe impl Send for Sign {}
-#[no_mangle]
-/// Creates a copy of a Sign
-pub extern "C" fn Sign_clone(orig: &Sign) -> Sign {
-       Sign {
-               this_arg: if let Some(f) = orig.clone { (f)(orig.this_arg) } else { orig.this_arg },
-               get_per_commitment_point: orig.get_per_commitment_point.clone(),
-               release_commitment_secret: orig.release_commitment_secret.clone(),
-               pubkeys: orig.pubkeys.clone(),
-               set_pubkeys: orig.set_pubkeys.clone(),
-               channel_keys_id: orig.channel_keys_id.clone(),
-               sign_counterparty_commitment: orig.sign_counterparty_commitment.clone(),
-               sign_holder_commitment_and_htlcs: orig.sign_holder_commitment_and_htlcs.clone(),
-               sign_justice_transaction: orig.sign_justice_transaction.clone(),
-               sign_counterparty_htlc_transaction: orig.sign_counterparty_htlc_transaction.clone(),
-               sign_closing_transaction: orig.sign_closing_transaction.clone(),
-               sign_channel_announcement: orig.sign_channel_announcement.clone(),
-               ready_channel: orig.ready_channel.clone(),
-               clone: orig.clone.clone(),
-               write: orig.write.clone(),
-               free: orig.free.clone(),
-       }
-}
-impl Clone for Sign {
-       fn clone(&self) -> Self {
-               Sign_clone(self)
-       }
-}
-impl lightning::util::ser::Writeable for Sign {
-       fn write<W: lightning::util::ser::Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
-               let vec = (self.write)(self.this_arg);
-               w.write_all(vec.as_slice())
-       }
-}
+unsafe impl Send for BaseSign {}
 
-use lightning::chain::keysinterface::Sign as rustSign;
-impl rustSign for Sign {
-       fn get_per_commitment_point<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, idx: u64, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> bitcoin::secp256k1::key::PublicKey {
+use lightning::chain::keysinterface::BaseSign as rustBaseSign;
+impl rustBaseSign for BaseSign {
+       fn get_per_commitment_point(&self, idx: u64, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> bitcoin::secp256k1::key::PublicKey {
                let mut ret = (self.get_per_commitment_point)(self.this_arg, idx);
                ret.into_rust()
        }
@@ -650,7 +611,7 @@ impl rustSign for Sign {
        }
        fn pubkeys(&self) -> &lightning::ln::chan_utils::ChannelPublicKeys {
                if let Some(f) = self.set_pubkeys {
-                       (f)(self);
+                       (f)(&self);
                }
                unsafe { &*self.pubkeys.inner }
        }
@@ -658,36 +619,36 @@ impl rustSign for Sign {
                let mut ret = (self.channel_keys_id)(self.this_arg);
                ret.data
        }
-       fn sign_counterparty_commitment<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, commitment_tx: &lightning::ln::chan_utils::CommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<(bitcoin::secp256k1::Signature, Vec<bitcoin::secp256k1::Signature>), ()> {
+       fn sign_counterparty_commitment(&self, commitment_tx: &lightning::ln::chan_utils::CommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<(bitcoin::secp256k1::Signature, Vec<bitcoin::secp256k1::Signature>), ()> {
                let mut ret = (self.sign_counterparty_commitment)(self.this_arg, &crate::ln::chan_utils::CommitmentTransaction { inner: unsafe { (commitment_tx as *const _) as *mut _ }, is_owned: false });
                let mut local_ret = match ret.result_ok { true => Ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).to_rust(); let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.into_rust().drain(..) { local_orig_ret_0_1.push( { item.into_rust() }); }; let mut local_ret_0 = (orig_ret_0_0.into_rust(), local_orig_ret_0_1); local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
                local_ret
        }
-       fn sign_holder_commitment_and_htlcs<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, commitment_tx: &lightning::ln::chan_utils::HolderCommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<(bitcoin::secp256k1::Signature, Vec<bitcoin::secp256k1::Signature>), ()> {
+       fn sign_holder_commitment_and_htlcs(&self, commitment_tx: &lightning::ln::chan_utils::HolderCommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<(bitcoin::secp256k1::Signature, Vec<bitcoin::secp256k1::Signature>), ()> {
                let mut ret = (self.sign_holder_commitment_and_htlcs)(self.this_arg, &crate::ln::chan_utils::HolderCommitmentTransaction { inner: unsafe { (commitment_tx as *const _) as *mut _ }, is_owned: false });
                let mut local_ret = match ret.result_ok { true => Ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).to_rust(); let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.into_rust().drain(..) { local_orig_ret_0_1.push( { item.into_rust() }); }; let mut local_ret_0 = (orig_ret_0_0.into_rust(), local_orig_ret_0_1); local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
                local_ret
        }
-       fn sign_justice_transaction<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, justice_tx: &bitcoin::blockdata::transaction::Transaction, input: usize, amount: u64, per_commitment_key: &bitcoin::secp256k1::key::SecretKey, htlc: &Option<lightning::ln::chan_utils::HTLCOutputInCommitment>, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
+       fn sign_justice_transaction(&self, justice_tx: &bitcoin::blockdata::transaction::Transaction, input: usize, amount: u64, per_commitment_key: &bitcoin::secp256k1::key::SecretKey, htlc: &Option<lightning::ln::chan_utils::HTLCOutputInCommitment>, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<bitcoin::secp256k1::Signature, ()> {
                let mut local_justice_tx = ::bitcoin::consensus::encode::serialize(justice_tx);
                let mut local_htlc = &crate::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (if htlc.is_none() { std::ptr::null() } else {  { (htlc.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
                let mut ret = (self.sign_justice_transaction)(self.this_arg, crate::c_types::Transaction::from_vec(local_justice_tx), input, amount, per_commitment_key.as_ref(), local_htlc);
                let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
                local_ret
        }
-       fn sign_counterparty_htlc_transaction<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, htlc_tx: &bitcoin::blockdata::transaction::Transaction, input: usize, amount: u64, per_commitment_point: &bitcoin::secp256k1::key::PublicKey, htlc: &lightning::ln::chan_utils::HTLCOutputInCommitment, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
+       fn sign_counterparty_htlc_transaction(&self, htlc_tx: &bitcoin::blockdata::transaction::Transaction, input: usize, amount: u64, per_commitment_point: &bitcoin::secp256k1::key::PublicKey, htlc: &lightning::ln::chan_utils::HTLCOutputInCommitment, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<bitcoin::secp256k1::Signature, ()> {
                let mut local_htlc_tx = ::bitcoin::consensus::encode::serialize(htlc_tx);
                let mut ret = (self.sign_counterparty_htlc_transaction)(self.this_arg, crate::c_types::Transaction::from_vec(local_htlc_tx), input, amount, crate::c_types::PublicKey::from_rust(&per_commitment_point), &crate::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (htlc as *const _) as *mut _ }, is_owned: false });
                let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
                local_ret
        }
-       fn sign_closing_transaction<T:bitcoin::secp256k1::Signing>(&self, closing_tx: &bitcoin::blockdata::transaction::Transaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
+       fn sign_closing_transaction(&self, closing_tx: &bitcoin::blockdata::transaction::Transaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<bitcoin::secp256k1::Signature, ()> {
                let mut local_closing_tx = ::bitcoin::consensus::encode::serialize(closing_tx);
                let mut ret = (self.sign_closing_transaction)(self.this_arg, crate::c_types::Transaction::from_vec(local_closing_tx));
                let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
                local_ret
        }
-       fn sign_channel_announcement<T:bitcoin::secp256k1::Signing>(&self, msg: &lightning::ln::msgs::UnsignedChannelAnnouncement, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
+       fn sign_channel_announcement(&self, msg: &lightning::ln::msgs::UnsignedChannelAnnouncement, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<bitcoin::secp256k1::Signature, ()> {
                let mut ret = (self.sign_channel_announcement)(self.this_arg, &crate::ln::msgs::UnsignedChannelAnnouncement { inner: unsafe { (msg as *const _) as *mut _ }, is_owned: false });
                let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
                local_ret
@@ -697,6 +658,135 @@ impl rustSign for Sign {
        }
 }
 
+// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
+// directly as a Deref trait in higher-level structs:
+impl std::ops::Deref for BaseSign {
+       type Target = Self;
+       fn deref(&self) -> &Self {
+               self
+       }
+}
+/// Calls the free function if one is set
+#[no_mangle]
+pub extern "C" fn BaseSign_free(this_ptr: BaseSign) { }
+impl Drop for BaseSign {
+       fn drop(&mut self) {
+               if let Some(f) = self.free {
+                       f(self.this_arg);
+               }
+       }
+}
+/// A cloneable signer.
+///
+/// Although we require signers to be cloneable, it may be useful for developers to be able to use
+/// signers in an un-sized way, for example as `dyn BaseSign`. Therefore we separate the Clone trait,
+/// which implies Sized, into this derived trait.
+#[repr(C)]
+pub struct Sign {
+       /// An opaque pointer which is passed to your function implementations as an argument.
+       /// This has no meaning in the LDK, and can be NULL or any other value.
+       pub this_arg: *mut c_void,
+       /// Implementation of BaseSign for this object.
+       pub BaseSign: crate::chain::keysinterface::BaseSign,
+       /// Creates a copy of the BaseSign, for a copy of this Sign.
+       /// Because BaseSign doesn't natively support copying itself, you have to provide a full copy implementation here.
+       pub BaseSign_clone: extern "C" fn (orig_BaseSign: &BaseSign) -> BaseSign,
+       /// Serialize the object into a byte array
+       pub write: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_u8Z,
+       /// Creates a copy of the object pointed to by this_arg, for a copy of this Sign.
+       /// Note that the ultimate copy of the Sign will have all function pointers the same as the original.
+       /// May be NULL if no action needs to be taken, the this_arg pointer will be copied into the new Sign.
+       pub clone: Option<extern "C" fn (this_arg: *const c_void) -> *mut c_void>,
+       /// Frees any resources associated with this object given its this_arg pointer.
+       /// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed.
+       pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
+}
+impl lightning::chain::keysinterface::BaseSign for Sign {
+       fn get_per_commitment_point(&self, idx: u64, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> bitcoin::secp256k1::key::PublicKey {
+               let mut ret = (self.BaseSign.get_per_commitment_point)(self.this_arg, idx);
+               ret.into_rust()
+       }
+       fn release_commitment_secret(&self, idx: u64) -> [u8; 32] {
+               let mut ret = (self.BaseSign.release_commitment_secret)(self.this_arg, idx);
+               ret.data
+       }
+       fn pubkeys(&self) -> &lightning::ln::chan_utils::ChannelPublicKeys {
+               if let Some(f) = self.BaseSign.set_pubkeys {
+                       (f)(&self.BaseSign);
+               }
+               unsafe { &*self.BaseSign.pubkeys.inner }
+       }
+       fn channel_keys_id(&self) -> [u8; 32] {
+               let mut ret = (self.BaseSign.channel_keys_id)(self.this_arg);
+               ret.data
+       }
+       fn sign_counterparty_commitment(&self, commitment_tx: &lightning::ln::chan_utils::CommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<(bitcoin::secp256k1::Signature, Vec<bitcoin::secp256k1::Signature>), ()> {
+               let mut ret = (self.BaseSign.sign_counterparty_commitment)(self.this_arg, &crate::ln::chan_utils::CommitmentTransaction { inner: unsafe { (commitment_tx as *const _) as *mut _ }, is_owned: false });
+               let mut local_ret = match ret.result_ok { true => Ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).to_rust(); let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.into_rust().drain(..) { local_orig_ret_0_1.push( { item.into_rust() }); }; let mut local_ret_0 = (orig_ret_0_0.into_rust(), local_orig_ret_0_1); local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
+               local_ret
+       }
+       fn sign_holder_commitment_and_htlcs(&self, commitment_tx: &lightning::ln::chan_utils::HolderCommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<(bitcoin::secp256k1::Signature, Vec<bitcoin::secp256k1::Signature>), ()> {
+               let mut ret = (self.BaseSign.sign_holder_commitment_and_htlcs)(self.this_arg, &crate::ln::chan_utils::HolderCommitmentTransaction { inner: unsafe { (commitment_tx as *const _) as *mut _ }, is_owned: false });
+               let mut local_ret = match ret.result_ok { true => Ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).to_rust(); let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.into_rust().drain(..) { local_orig_ret_0_1.push( { item.into_rust() }); }; let mut local_ret_0 = (orig_ret_0_0.into_rust(), local_orig_ret_0_1); local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
+               local_ret
+       }
+       fn sign_justice_transaction(&self, justice_tx: &bitcoin::blockdata::transaction::Transaction, input: usize, amount: u64, per_commitment_key: &bitcoin::secp256k1::key::SecretKey, htlc: &Option<lightning::ln::chan_utils::HTLCOutputInCommitment>, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<bitcoin::secp256k1::Signature, ()> {
+               let mut local_justice_tx = ::bitcoin::consensus::encode::serialize(justice_tx);
+               let mut local_htlc = &crate::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (if htlc.is_none() { std::ptr::null() } else {  { (htlc.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
+               let mut ret = (self.BaseSign.sign_justice_transaction)(self.this_arg, crate::c_types::Transaction::from_vec(local_justice_tx), input, amount, per_commitment_key.as_ref(), local_htlc);
+               let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
+               local_ret
+       }
+       fn sign_counterparty_htlc_transaction(&self, htlc_tx: &bitcoin::blockdata::transaction::Transaction, input: usize, amount: u64, per_commitment_point: &bitcoin::secp256k1::key::PublicKey, htlc: &lightning::ln::chan_utils::HTLCOutputInCommitment, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<bitcoin::secp256k1::Signature, ()> {
+               let mut local_htlc_tx = ::bitcoin::consensus::encode::serialize(htlc_tx);
+               let mut ret = (self.BaseSign.sign_counterparty_htlc_transaction)(self.this_arg, crate::c_types::Transaction::from_vec(local_htlc_tx), input, amount, crate::c_types::PublicKey::from_rust(&per_commitment_point), &crate::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (htlc as *const _) as *mut _ }, is_owned: false });
+               let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
+               local_ret
+       }
+       fn sign_closing_transaction(&self, closing_tx: &bitcoin::blockdata::transaction::Transaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<bitcoin::secp256k1::Signature, ()> {
+               let mut local_closing_tx = ::bitcoin::consensus::encode::serialize(closing_tx);
+               let mut ret = (self.BaseSign.sign_closing_transaction)(self.this_arg, crate::c_types::Transaction::from_vec(local_closing_tx));
+               let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
+               local_ret
+       }
+       fn sign_channel_announcement(&self, msg: &lightning::ln::msgs::UnsignedChannelAnnouncement, _secp_ctx: &bitcoin::secp256k1::Secp256k1<bitcoin::secp256k1::All>) -> Result<bitcoin::secp256k1::Signature, ()> {
+               let mut ret = (self.BaseSign.sign_channel_announcement)(self.this_arg, &crate::ln::msgs::UnsignedChannelAnnouncement { inner: unsafe { (msg as *const _) as *mut _ }, is_owned: false });
+               let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })};
+               local_ret
+       }
+       fn ready_channel(&mut self, channel_parameters: &lightning::ln::chan_utils::ChannelTransactionParameters) {
+               (self.BaseSign.ready_channel)(self.this_arg, &crate::ln::chan_utils::ChannelTransactionParameters { inner: unsafe { (channel_parameters as *const _) as *mut _ }, is_owned: false })
+       }
+}
+unsafe impl Send for Sign {}
+impl lightning::util::ser::Writeable for Sign {
+       fn write<W: lightning::util::ser::Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+               let vec = (self.write)(self.this_arg);
+               w.write_all(vec.as_slice())
+       }
+}
+#[no_mangle]
+/// Creates a copy of a Sign
+pub extern "C" fn Sign_clone(orig: &Sign) -> Sign {
+       Sign {
+               this_arg: if let Some(f) = orig.clone { (f)(orig.this_arg) } else { orig.this_arg },
+               BaseSign: (orig.BaseSign_clone)(&orig.BaseSign),
+               BaseSign_clone: orig.BaseSign_clone,
+               write: Clone::clone(&orig.write),
+               clone: Clone::clone(&orig.clone),
+               free: Clone::clone(&orig.free),
+       }
+}
+impl Clone for Sign {
+       fn clone(&self) -> Self {
+               Sign_clone(self)
+       }
+}
+
+use lightning::chain::keysinterface::Sign as rustSign;
+impl rustSign for Sign {
+}
+
 // We're essentially a pointer already, or at least a set of pointers, so allow us to be used
 // directly as a Deref trait in higher-level structs:
 impl std::ops::Deref for Sign {
@@ -1044,107 +1134,165 @@ pub extern "C" fn InMemorySigner_sign_dynamic_p2wsh_input(this_arg: &InMemorySig
        local_ret
 }
 
-impl From<nativeInMemorySigner> for crate::chain::keysinterface::Sign {
+impl From<nativeInMemorySigner> for crate::chain::keysinterface::BaseSign {
        fn from(obj: nativeInMemorySigner) -> Self {
                let mut rust_obj = InMemorySigner { inner: Box::into_raw(Box::new(obj)), is_owned: true };
-               let mut ret = InMemorySigner_as_Sign(&rust_obj);
+               let mut ret = InMemorySigner_as_BaseSign(&rust_obj);
                // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn
                rust_obj.inner = std::ptr::null_mut();
                ret.free = Some(InMemorySigner_free_void);
                ret
        }
 }
-/// Constructs a new Sign which calls the relevant methods on this_arg.
-/// This copies the `inner` pointer in this_arg and thus the returned Sign must be freed before this_arg is
+/// Constructs a new BaseSign which calls the relevant methods on this_arg.
+/// This copies the `inner` pointer in this_arg and thus the returned BaseSign must be freed before this_arg is
 #[no_mangle]
-pub extern "C" fn InMemorySigner_as_Sign(this_arg: &InMemorySigner) -> crate::chain::keysinterface::Sign {
-       crate::chain::keysinterface::Sign {
+pub extern "C" fn InMemorySigner_as_BaseSign(this_arg: &InMemorySigner) -> crate::chain::keysinterface::BaseSign {
+       crate::chain::keysinterface::BaseSign {
                this_arg: unsafe { (*this_arg).inner as *mut c_void },
                free: None,
-               get_per_commitment_point: InMemorySigner_Sign_get_per_commitment_point,
-               release_commitment_secret: InMemorySigner_Sign_release_commitment_secret,
+               get_per_commitment_point: InMemorySigner_BaseSign_get_per_commitment_point,
+               release_commitment_secret: InMemorySigner_BaseSign_release_commitment_secret,
 
                pubkeys: crate::ln::chan_utils::ChannelPublicKeys { inner: std::ptr::null_mut(), is_owned: true },
-               set_pubkeys: Some(InMemorySigner_Sign_set_pubkeys),
-               channel_keys_id: InMemorySigner_Sign_channel_keys_id,
-               sign_counterparty_commitment: InMemorySigner_Sign_sign_counterparty_commitment,
-               sign_holder_commitment_and_htlcs: InMemorySigner_Sign_sign_holder_commitment_and_htlcs,
-               sign_justice_transaction: InMemorySigner_Sign_sign_justice_transaction,
-               sign_counterparty_htlc_transaction: InMemorySigner_Sign_sign_counterparty_htlc_transaction,
-               sign_closing_transaction: InMemorySigner_Sign_sign_closing_transaction,
-               sign_channel_announcement: InMemorySigner_Sign_sign_channel_announcement,
-               ready_channel: InMemorySigner_Sign_ready_channel,
-               clone: Some(InMemorySigner_clone_void),
-               write: InMemorySigner_write_void,
+               set_pubkeys: Some(InMemorySigner_BaseSign_set_pubkeys),
+               channel_keys_id: InMemorySigner_BaseSign_channel_keys_id,
+               sign_counterparty_commitment: InMemorySigner_BaseSign_sign_counterparty_commitment,
+               sign_holder_commitment_and_htlcs: InMemorySigner_BaseSign_sign_holder_commitment_and_htlcs,
+               sign_justice_transaction: InMemorySigner_BaseSign_sign_justice_transaction,
+               sign_counterparty_htlc_transaction: InMemorySigner_BaseSign_sign_counterparty_htlc_transaction,
+               sign_closing_transaction: InMemorySigner_BaseSign_sign_closing_transaction,
+               sign_channel_announcement: InMemorySigner_BaseSign_sign_channel_announcement,
+               ready_channel: InMemorySigner_BaseSign_ready_channel,
        }
 }
 
 #[must_use]
-extern "C" fn InMemorySigner_Sign_get_per_commitment_point(this_arg: *const c_void, mut idx: u64) -> crate::c_types::PublicKey {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::get_per_commitment_point(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, idx, secp256k1::SECP256K1);
+extern "C" fn InMemorySigner_BaseSign_get_per_commitment_point(this_arg: *const c_void, mut idx: u64) -> crate::c_types::PublicKey {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::get_per_commitment_point(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, idx, secp256k1::SECP256K1);
        crate::c_types::PublicKey::from_rust(&ret)
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_release_commitment_secret(this_arg: *const c_void, mut idx: u64) -> crate::c_types::ThirtyTwoBytes {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::release_commitment_secret(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, idx);
+extern "C" fn InMemorySigner_BaseSign_release_commitment_secret(this_arg: *const c_void, mut idx: u64) -> crate::c_types::ThirtyTwoBytes {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::release_commitment_secret(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, idx);
        crate::c_types::ThirtyTwoBytes { data: ret }
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_pubkeys(this_arg: *const c_void) -> crate::ln::chan_utils::ChannelPublicKeys {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::pubkeys(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, );
+extern "C" fn InMemorySigner_BaseSign_pubkeys(this_arg: *const c_void) -> crate::ln::chan_utils::ChannelPublicKeys {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::pubkeys(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, );
        crate::ln::chan_utils::ChannelPublicKeys { inner: unsafe { ( (&(*ret) as *const _) as *mut _) }, is_owned: false }
 }
-extern "C" fn InMemorySigner_Sign_set_pubkeys(trait_self_arg: &Sign) {
+extern "C" fn InMemorySigner_BaseSign_set_pubkeys(trait_self_arg: &BaseSign) {
        // This is a bit race-y in the general case, but for our specific use-cases today, we're safe
        // Specifically, we must ensure that the first time we're called it can never be in parallel
        if trait_self_arg.pubkeys.inner.is_null() {
-               unsafe { &mut *(trait_self_arg as *const Sign  as *mut Sign) }.pubkeys = InMemorySigner_Sign_pubkeys(trait_self_arg.this_arg);
+               unsafe { &mut *(trait_self_arg as *const BaseSign  as *mut BaseSign) }.pubkeys = InMemorySigner_BaseSign_pubkeys(trait_self_arg.this_arg);
        }
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_channel_keys_id(this_arg: *const c_void) -> crate::c_types::ThirtyTwoBytes {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::channel_keys_id(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, );
+extern "C" fn InMemorySigner_BaseSign_channel_keys_id(this_arg: *const c_void) -> crate::c_types::ThirtyTwoBytes {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::channel_keys_id(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, );
        crate::c_types::ThirtyTwoBytes { data: ret }
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_sign_counterparty_commitment(this_arg: *const c_void, commitment_tx: &crate::ln::chan_utils::CommitmentTransaction) -> crate::c_types::derived::CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::sign_counterparty_commitment(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, unsafe { &*commitment_tx.inner }, secp256k1::SECP256K1);
+extern "C" fn InMemorySigner_BaseSign_sign_counterparty_commitment(this_arg: *const c_void, commitment_tx: &crate::ln::chan_utils::CommitmentTransaction) -> crate::c_types::derived::CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::sign_counterparty_commitment(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, unsafe { &*commitment_tx.inner }, secp256k1::SECP256K1);
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = o; let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.drain(..) { local_orig_ret_0_1.push( { crate::c_types::Signature::from_rust(&item) }); }; let mut local_ret_0 = (crate::c_types::Signature::from_rust(&orig_ret_0_0), local_orig_ret_0_1.into()).into(); local_ret_0 }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }).into() };
        local_ret
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_sign_holder_commitment_and_htlcs(this_arg: *const c_void, commitment_tx: &crate::ln::chan_utils::HolderCommitmentTransaction) -> crate::c_types::derived::CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::sign_holder_commitment_and_htlcs(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, unsafe { &*commitment_tx.inner }, secp256k1::SECP256K1);
+extern "C" fn InMemorySigner_BaseSign_sign_holder_commitment_and_htlcs(this_arg: *const c_void, commitment_tx: &crate::ln::chan_utils::HolderCommitmentTransaction) -> crate::c_types::derived::CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::sign_holder_commitment_and_htlcs(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, unsafe { &*commitment_tx.inner }, secp256k1::SECP256K1);
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = o; let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.drain(..) { local_orig_ret_0_1.push( { crate::c_types::Signature::from_rust(&item) }); }; let mut local_ret_0 = (crate::c_types::Signature::from_rust(&orig_ret_0_0), local_orig_ret_0_1.into()).into(); local_ret_0 }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }).into() };
        local_ret
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_sign_justice_transaction(this_arg: *const c_void, mut justice_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, per_commitment_key: *const [u8; 32], htlc: &crate::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ {
+extern "C" fn InMemorySigner_BaseSign_sign_justice_transaction(this_arg: *const c_void, mut justice_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, per_commitment_key: *const [u8; 32], htlc: &crate::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ {
        let mut local_htlc = if htlc.inner.is_null() { None } else { Some((* { unsafe { &*htlc.inner } }).clone()) };
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::sign_justice_transaction(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &justice_tx.into_bitcoin(), input, amount, &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *per_commitment_key}[..]).unwrap(), &local_htlc, secp256k1::SECP256K1);
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::sign_justice_transaction(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &justice_tx.into_bitcoin(), input, amount, &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *per_commitment_key}[..]).unwrap(), &local_htlc, secp256k1::SECP256K1);
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }).into() };
        local_ret
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_sign_counterparty_htlc_transaction(this_arg: *const c_void, mut htlc_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, mut per_commitment_point: crate::c_types::PublicKey, htlc: &crate::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::sign_counterparty_htlc_transaction(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &htlc_tx.into_bitcoin(), input, amount, &per_commitment_point.into_rust(), unsafe { &*htlc.inner }, secp256k1::SECP256K1);
+extern "C" fn InMemorySigner_BaseSign_sign_counterparty_htlc_transaction(this_arg: *const c_void, mut htlc_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, mut per_commitment_point: crate::c_types::PublicKey, htlc: &crate::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::sign_counterparty_htlc_transaction(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &htlc_tx.into_bitcoin(), input, amount, &per_commitment_point.into_rust(), unsafe { &*htlc.inner }, secp256k1::SECP256K1);
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }).into() };
        local_ret
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_sign_closing_transaction(this_arg: *const c_void, mut closing_tx: crate::c_types::Transaction) -> crate::c_types::derived::CResult_SignatureNoneZ {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::sign_closing_transaction(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &closing_tx.into_bitcoin(), secp256k1::SECP256K1);
+extern "C" fn InMemorySigner_BaseSign_sign_closing_transaction(this_arg: *const c_void, mut closing_tx: crate::c_types::Transaction) -> crate::c_types::derived::CResult_SignatureNoneZ {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::sign_closing_transaction(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &closing_tx.into_bitcoin(), secp256k1::SECP256K1);
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }).into() };
        local_ret
 }
 #[must_use]
-extern "C" fn InMemorySigner_Sign_sign_channel_announcement(this_arg: *const c_void, msg: &crate::ln::msgs::UnsignedChannelAnnouncement) -> crate::c_types::derived::CResult_SignatureNoneZ {
-       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::sign_channel_announcement(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, unsafe { &*msg.inner }, secp256k1::SECP256K1);
+extern "C" fn InMemorySigner_BaseSign_sign_channel_announcement(this_arg: *const c_void, msg: &crate::ln::msgs::UnsignedChannelAnnouncement) -> crate::c_types::derived::CResult_SignatureNoneZ {
+       let mut ret = <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::sign_channel_announcement(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, unsafe { &*msg.inner }, secp256k1::SECP256K1);
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }).into() };
        local_ret
 }
-extern "C" fn InMemorySigner_Sign_ready_channel(this_arg: *mut c_void, channel_parameters: &crate::ln::chan_utils::ChannelTransactionParameters) {
-       <nativeInMemorySigner as lightning::chain::keysinterface::Sign<>>::ready_channel(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, unsafe { &*channel_parameters.inner })
+extern "C" fn InMemorySigner_BaseSign_ready_channel(this_arg: *mut c_void, channel_parameters: &crate::ln::chan_utils::ChannelTransactionParameters) {
+       <nativeInMemorySigner as lightning::chain::keysinterface::BaseSign<>>::ready_channel(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, unsafe { &*channel_parameters.inner })
+}
+
+impl From<nativeInMemorySigner> for crate::chain::keysinterface::Sign {
+       fn from(obj: nativeInMemorySigner) -> Self {
+               let mut rust_obj = InMemorySigner { inner: Box::into_raw(Box::new(obj)), is_owned: true };
+               let mut ret = InMemorySigner_as_Sign(&rust_obj);
+               // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn
+               rust_obj.inner = std::ptr::null_mut();
+               ret.free = Some(InMemorySigner_free_void);
+               ret
+       }
+}
+/// Constructs a new Sign which calls the relevant methods on this_arg.
+/// This copies the `inner` pointer in this_arg and thus the returned Sign must be freed before this_arg is
+#[no_mangle]
+pub extern "C" fn InMemorySigner_as_Sign(this_arg: &InMemorySigner) -> crate::chain::keysinterface::Sign {
+       crate::chain::keysinterface::Sign {
+               this_arg: unsafe { (*this_arg).inner as *mut c_void },
+               free: None,
+               BaseSign: crate::chain::keysinterface::BaseSign {
+                       this_arg: unsafe { (*this_arg).inner as *mut c_void },
+                       free: None,
+                       get_per_commitment_point: InMemorySigner_BaseSign_get_per_commitment_point,
+                       release_commitment_secret: InMemorySigner_BaseSign_release_commitment_secret,
+
+                       pubkeys: crate::ln::chan_utils::ChannelPublicKeys { inner: std::ptr::null_mut(), is_owned: true },
+                       set_pubkeys: Some(InMemorySigner_BaseSign_set_pubkeys),
+                       channel_keys_id: InMemorySigner_BaseSign_channel_keys_id,
+                       sign_counterparty_commitment: InMemorySigner_BaseSign_sign_counterparty_commitment,
+                       sign_holder_commitment_and_htlcs: InMemorySigner_BaseSign_sign_holder_commitment_and_htlcs,
+                       sign_justice_transaction: InMemorySigner_BaseSign_sign_justice_transaction,
+                       sign_counterparty_htlc_transaction: InMemorySigner_BaseSign_sign_counterparty_htlc_transaction,
+                       sign_closing_transaction: InMemorySigner_BaseSign_sign_closing_transaction,
+                       sign_channel_announcement: InMemorySigner_BaseSign_sign_channel_announcement,
+                       ready_channel: InMemorySigner_BaseSign_ready_channel,
+               },
+               BaseSign_clone: InMemorySigner_BaseSign_clone,
+               write: InMemorySigner_write_void,
+               clone: Some(InMemorySigner_clone_void),
+       }
+}
+
+extern "C" fn InMemorySigner_BaseSign_clone(orig: &crate::chain::keysinterface::BaseSign) -> crate::chain::keysinterface::BaseSign {
+       crate::chain::keysinterface::BaseSign {
+               this_arg: orig.this_arg,
+               free: None,
+               get_per_commitment_point: InMemorySigner_BaseSign_get_per_commitment_point,
+               release_commitment_secret: InMemorySigner_BaseSign_release_commitment_secret,
+
+               pubkeys: crate::ln::chan_utils::ChannelPublicKeys { inner: std::ptr::null_mut(), is_owned: true },
+               set_pubkeys: Some(InMemorySigner_BaseSign_set_pubkeys),
+               channel_keys_id: InMemorySigner_BaseSign_channel_keys_id,
+               sign_counterparty_commitment: InMemorySigner_BaseSign_sign_counterparty_commitment,
+               sign_holder_commitment_and_htlcs: InMemorySigner_BaseSign_sign_holder_commitment_and_htlcs,
+               sign_justice_transaction: InMemorySigner_BaseSign_sign_justice_transaction,
+               sign_counterparty_htlc_transaction: InMemorySigner_BaseSign_sign_counterparty_htlc_transaction,
+               sign_closing_transaction: InMemorySigner_BaseSign_sign_closing_transaction,
+               sign_channel_announcement: InMemorySigner_BaseSign_sign_channel_announcement,
+               ready_channel: InMemorySigner_BaseSign_ready_channel,
+       }
 }
 
 #[no_mangle]
index 89a3b249e39078d61bf7915cf5b4e7471b940d3a..cad534b0cb66158fe1dd7daef0bcdbb9ba3f9b14 100644 (file)
@@ -597,10 +597,11 @@ pub extern "C" fn ChannelManager_new(mut fee_est: crate::chain::chaininterface::
 
 /// Creates a new outbound channel to the given remote node and with the given value.
 ///
-/// user_id will be provided back as user_channel_id in FundingGenerationReady and
-/// FundingBroadcastSafe events to allow tracking of which events correspond with which
-/// create_channel call. Note that user_channel_id defaults to 0 for inbound channels, so you
-/// may wish to avoid using 0 for user_id here.
+/// user_id will be provided back as user_channel_id in FundingGenerationReady events to allow
+/// tracking of which events correspond with which create_channel call. Note that the
+/// user_channel_id defaults to 0 for inbound channels, so you may wish to avoid using 0 for
+/// user_id here. user_id has no meaning inside of LDK, it is simply copied to events and
+/// otherwise ignored.
 ///
 /// If successful, will generate a SendOpenChannel message event, so you should probably poll
 /// PeerManager::process_events afterwards.
@@ -719,16 +720,28 @@ pub extern "C" fn ChannelManager_send_payment(this_arg: &ChannelManager, route:
 
 /// Call this upon creation of a funding transaction for the given channel.
 ///
-/// Note that ALL inputs in the transaction pointed to by funding_txo MUST spend SegWit outputs
-/// or your counterparty can steal your funds!
+/// Returns an [`APIError::APIMisuseError`] if the funding_transaction spent non-SegWit outputs
+/// or if no output was found which matches the parameters in [`Event::FundingGenerationReady`].
 ///
 /// Panics if a funding transaction has already been provided for this channel.
 ///
-/// May panic if the funding_txo is duplicative with some other channel (note that this should
-/// be trivially prevented by using unique funding transaction keys per-channel).
+/// May panic if the output found in the funding transaction is duplicative with some other
+/// channel (note that this should be trivially prevented by using unique funding transaction
+/// keys per-channel).
+///
+/// Do NOT broadcast the funding transaction yourself. When we have safely received our
+/// counterparty's signature the funding transaction will automatically be broadcast via the
+/// [`BroadcasterInterface`] provided when this `ChannelManager` was constructed.
+///
+/// Note that this includes RBF or similar transaction replacement strategies - lightning does
+/// not currently support replacing a funding transaction on an existing channel. Instead,
+/// create a new channel with a conflicting funding transaction.
+#[must_use]
 #[no_mangle]
-pub extern "C" fn ChannelManager_funding_transaction_generated(this_arg: &ChannelManager, temporary_channel_id: *const [u8; 32], mut funding_txo: crate::chain::transaction::OutPoint) {
-       unsafe { &*this_arg.inner }.funding_transaction_generated(unsafe { &*temporary_channel_id}, *unsafe { Box::from_raw(funding_txo.take_inner()) })
+pub extern "C" fn ChannelManager_funding_transaction_generated(this_arg: &ChannelManager, temporary_channel_id: *const [u8; 32], mut funding_transaction: crate::c_types::Transaction) -> crate::c_types::derived::CResult_NoneAPIErrorZ {
+       let mut ret = unsafe { &*this_arg.inner }.funding_transaction_generated(unsafe { &*temporary_channel_id}, funding_transaction.into_bitcoin());
+       let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::util::errors::APIError::native_into(e) }).into() };
+       local_ret
 }
 
 /// Generates a signed node_announcement from the given arguments and creates a
@@ -921,24 +934,49 @@ pub extern "C" fn ChannelManager_as_Listen(this_arg: &ChannelManager) -> crate::
 extern "C" fn ChannelManager_Listen_block_connected(this_arg: *const c_void, mut block: crate::c_types::u8slice, mut height: u32) {
        <nativeChannelManager as lightning::chain::Listen<>>::block_connected(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, &::bitcoin::consensus::encode::deserialize(block.to_slice()).unwrap(), height)
 }
-extern "C" fn ChannelManager_Listen_block_disconnected(this_arg: *const c_void, header: *const [u8; 80], mut _height: u32) {
-       <nativeChannelManager as lightning::chain::Listen<>>::block_disconnected(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, &::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), _height)
+extern "C" fn ChannelManager_Listen_block_disconnected(this_arg: *const c_void, header: *const [u8; 80], mut height: u32) {
+       <nativeChannelManager as lightning::chain::Listen<>>::block_disconnected(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, &::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), height)
 }
 
-/// Updates channel state based on transactions seen in a connected block.
+/// Updates channel state to take note of transactions which were confirmed in the given block
+/// at the given height.
+///
+/// Note that you must still call (or have called) [`update_best_block`] with the block
+/// information which is included here.
+///
+/// This method may be called before or after [`update_best_block`] for a given block's
+/// transaction data and may be called multiple times with additional transaction data for a
+/// given block.
+///
+/// This method may be called for a previous block after an [`update_best_block`] call has
+/// been made for a later block, however it must *not* be called with transaction data from a
+/// block which is no longer in the best chain (ie where [`update_best_block`] has already
+/// been informed about a blockchain reorganization which no longer includes the block which
+/// corresponds to `header`).
+///
+/// [`update_best_block`]: `Self::update_best_block`
 #[no_mangle]
-pub extern "C" fn ChannelManager_block_connected(this_arg: &ChannelManager, header: *const [u8; 80], mut txdata: crate::c_types::derived::CVec_C2Tuple_usizeTransactionZZ, mut height: u32) {
+pub extern "C" fn ChannelManager_transactions_confirmed(this_arg: &ChannelManager, header: *const [u8; 80], mut height: u32, mut txdata: crate::c_types::derived::CVec_C2Tuple_usizeTransactionZZ) {
        let mut local_txdata = Vec::new(); for mut item in txdata.into_rust().drain(..) { local_txdata.push( { let (mut orig_txdata_0_0, mut orig_txdata_0_1) = item.to_rust(); let mut local_txdata_0 = (orig_txdata_0_0, orig_txdata_0_1.into_bitcoin()); local_txdata_0 }); };
-       unsafe { &*this_arg.inner }.block_connected(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), &local_txdata.iter().map(|(a, b)| (*a, b)).collect::<Vec<_>>()[..], height)
+       unsafe { &*this_arg.inner }.transactions_confirmed(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), height, &local_txdata.iter().map(|(a, b)| (*a, b)).collect::<Vec<_>>()[..])
 }
 
-/// Updates channel state based on a disconnected block.
+/// Updates channel state with the current best blockchain tip. You should attempt to call this
+/// quickly after a new block becomes available, however if multiple new blocks become
+/// available at the same time, only a single `update_best_block()` call needs to be made.
+///
+/// This method should also be called immediately after any block disconnections, once at the
+/// reorganization fork point, and once with the new chain tip. Calling this method at the
+/// blockchain reorganization fork point ensures we learn when a funding transaction which was
+/// previously confirmed is reorganized out of the blockchain, ensuring we do not continue to
+/// accept payments which cannot be enforced on-chain.
 ///
-/// If necessary, the channel may be force-closed without letting the counterparty participate
-/// in the shutdown.
+/// In both the block-connection and block-disconnection case, this method may be called either
+/// once per block connected or disconnected, or simply at the fork point and new tip(s),
+/// skipping any intermediary blocks.
 #[no_mangle]
-pub extern "C" fn ChannelManager_block_disconnected(this_arg: &ChannelManager, header: *const [u8; 80]) {
-       unsafe { &*this_arg.inner }.block_disconnected(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap())
+pub extern "C" fn ChannelManager_update_best_block(this_arg: &ChannelManager, header: *const [u8; 80], mut height: u32) {
+       unsafe { &*this_arg.inner }.update_best_block(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), height)
 }
 
 /// Blocks until ChannelManager needs to be persisted or a timeout is reached. It returns a bool
@@ -1001,7 +1039,7 @@ pub extern "C" fn ChannelManager_as_ChannelMessageHandler(this_arg: &ChannelMana
                MessageSendEventsProvider: crate::util::events::MessageSendEventsProvider {
                        this_arg: unsafe { (*this_arg).inner as *mut c_void },
                        free: None,
-                       get_and_clear_pending_msg_events: ChannelManager_ChannelMessageHandler_get_and_clear_pending_msg_events,
+                       get_and_clear_pending_msg_events: ChannelManager_MessageSendEventsProvider_get_and_clear_pending_msg_events,
                },
        }
 }
@@ -1066,12 +1104,6 @@ extern "C" fn ChannelManager_ChannelMessageHandler_peer_connected(this_arg: *con
 extern "C" fn ChannelManager_ChannelMessageHandler_handle_error(this_arg: *const c_void, mut counterparty_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::ErrorMessage) {
        <nativeChannelManager as lightning::ln::msgs::ChannelMessageHandler<>>::handle_error(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, &counterparty_node_id.into_rust(), unsafe { &*msg.inner })
 }
-#[must_use]
-extern "C" fn ChannelManager_ChannelMessageHandler_get_and_clear_pending_msg_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_MessageSendEventZ {
-       let mut ret = <nativeChannelManager as lightning::util::events::MessageSendEventsProvider<>>::get_and_clear_pending_msg_events(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, );
-       let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::util::events::MessageSendEvent::native_into(item) }); };
-       local_ret.into()
-}
 
 #[no_mangle]
 /// Serialize the ChannelManager object into a byte array which can be read by ChannelManager_read
index 5f32cacfbaeb0ccd371a6209f05a4c91ce689c16..67d2f0b3b11749acc6844b9822875319eaeca318 100644 (file)
@@ -4512,7 +4512,7 @@ pub struct ChannelMessageHandler {
        pub handle_channel_update: extern "C" fn (this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::ChannelUpdate),
        /// Handle an incoming error message from the given peer.
        pub handle_error: extern "C" fn (this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::ErrorMessage),
-/// Implementation of MessageSendEventsProvider for this object.
+       /// Implementation of MessageSendEventsProvider for this object.
        pub MessageSendEventsProvider: crate::util::events::MessageSendEventsProvider,
        /// Frees any resources associated with this object given its this_arg pointer.
        /// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed.
@@ -4520,7 +4520,9 @@ pub struct ChannelMessageHandler {
 }
 impl lightning::util::events::MessageSendEventsProvider for ChannelMessageHandler {
        fn get_and_clear_pending_msg_events(&self) -> Vec<lightning::util::events::MessageSendEvent> {
-               <crate::util::events::MessageSendEventsProvider as lightning::util::events::MessageSendEventsProvider>::get_and_clear_pending_msg_events(&self.MessageSendEventsProvider)
+               let mut ret = (self.MessageSendEventsProvider.get_and_clear_pending_msg_events)(self.this_arg);
+               let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { item.into_native() }); };
+               local_ret
        }
 }
 unsafe impl Send for ChannelMessageHandler {}
@@ -4668,7 +4670,7 @@ pub struct RoutingMessageHandler {
        /// list of short_channel_ids.
        #[must_use]
        pub handle_query_short_channel_ids: extern "C" fn (this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: crate::ln::msgs::QueryShortChannelIds) -> crate::c_types::derived::CResult_NoneLightningErrorZ,
-/// Implementation of MessageSendEventsProvider for this object.
+       /// Implementation of MessageSendEventsProvider for this object.
        pub MessageSendEventsProvider: crate::util::events::MessageSendEventsProvider,
        /// Frees any resources associated with this object given its this_arg pointer.
        /// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed.
@@ -4678,7 +4680,9 @@ unsafe impl Send for RoutingMessageHandler {}
 unsafe impl Sync for RoutingMessageHandler {}
 impl lightning::util::events::MessageSendEventsProvider for RoutingMessageHandler {
        fn get_and_clear_pending_msg_events(&self) -> Vec<lightning::util::events::MessageSendEvent> {
-               <crate::util::events::MessageSendEventsProvider as lightning::util::events::MessageSendEventsProvider>::get_and_clear_pending_msg_events(&self.MessageSendEventsProvider)
+               let mut ret = (self.MessageSendEventsProvider.get_and_clear_pending_msg_events)(self.this_arg);
+               let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { item.into_native() }); };
+               local_ret
        }
 }
 
index 9f3f8409cfc9484da166c1abb6ae0b45487621a7..07368ae85ce9eca703f593b39a6e22747e223927 100644 (file)
@@ -130,7 +130,7 @@ pub extern "C" fn IgnoringMessageHandler_as_RoutingMessageHandler(this_arg: &Ign
                MessageSendEventsProvider: crate::util::events::MessageSendEventsProvider {
                        this_arg: unsafe { (*this_arg).inner as *mut c_void },
                        free: None,
-                       get_and_clear_pending_msg_events: IgnoringMessageHandler_RoutingMessageHandler_get_and_clear_pending_msg_events,
+                       get_and_clear_pending_msg_events: IgnoringMessageHandler_MessageSendEventsProvider_get_and_clear_pending_msg_events,
                },
        }
 }
@@ -196,12 +196,6 @@ extern "C" fn IgnoringMessageHandler_RoutingMessageHandler_handle_query_short_ch
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::LightningError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() };
        local_ret
 }
-#[must_use]
-extern "C" fn IgnoringMessageHandler_RoutingMessageHandler_get_and_clear_pending_msg_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_MessageSendEventZ {
-       let mut ret = <nativeIgnoringMessageHandler as lightning::util::events::MessageSendEventsProvider<>>::get_and_clear_pending_msg_events(unsafe { &mut *(this_arg as *mut nativeIgnoringMessageHandler) }, );
-       let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::util::events::MessageSendEvent::native_into(item) }); };
-       local_ret.into()
-}
 
 
 use lightning::ln::peer_handler::ErroringMessageHandler as nativeErroringMessageHandlerImport;
@@ -325,7 +319,7 @@ pub extern "C" fn ErroringMessageHandler_as_ChannelMessageHandler(this_arg: &Err
                MessageSendEventsProvider: crate::util::events::MessageSendEventsProvider {
                        this_arg: unsafe { (*this_arg).inner as *mut c_void },
                        free: None,
-                       get_and_clear_pending_msg_events: ErroringMessageHandler_ChannelMessageHandler_get_and_clear_pending_msg_events,
+                       get_and_clear_pending_msg_events: ErroringMessageHandler_MessageSendEventsProvider_get_and_clear_pending_msg_events,
                },
        }
 }
@@ -390,12 +384,6 @@ extern "C" fn ErroringMessageHandler_ChannelMessageHandler_peer_connected(this_a
 extern "C" fn ErroringMessageHandler_ChannelMessageHandler_handle_error(this_arg: *const c_void, mut _their_node_id: crate::c_types::PublicKey, _msg: &crate::ln::msgs::ErrorMessage) {
        <nativeErroringMessageHandler as lightning::ln::msgs::ChannelMessageHandler<>>::handle_error(unsafe { &mut *(this_arg as *mut nativeErroringMessageHandler) }, &_their_node_id.into_rust(), unsafe { &*_msg.inner })
 }
-#[must_use]
-extern "C" fn ErroringMessageHandler_ChannelMessageHandler_get_and_clear_pending_msg_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_MessageSendEventZ {
-       let mut ret = <nativeErroringMessageHandler as lightning::util::events::MessageSendEventsProvider<>>::get_and_clear_pending_msg_events(unsafe { &mut *(this_arg as *mut nativeErroringMessageHandler) }, );
-       let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::util::events::MessageSendEvent::native_into(item) }); };
-       local_ret.into()
-}
 
 
 use lightning::ln::peer_handler::MessageHandler as nativeMessageHandlerImport;
@@ -540,12 +528,12 @@ impl std::hash::Hash for SocketDescriptor {
 pub extern "C" fn SocketDescriptor_clone(orig: &SocketDescriptor) -> SocketDescriptor {
        SocketDescriptor {
                this_arg: if let Some(f) = orig.clone { (f)(orig.this_arg) } else { orig.this_arg },
-               send_data: orig.send_data.clone(),
-               disconnect_socket: orig.disconnect_socket.clone(),
-               eq: orig.eq.clone(),
-               hash: orig.hash.clone(),
-               clone: orig.clone.clone(),
-               free: orig.free.clone(),
+               send_data: Clone::clone(&orig.send_data),
+               disconnect_socket: Clone::clone(&orig.disconnect_socket),
+               eq: Clone::clone(&orig.eq),
+               hash: Clone::clone(&orig.hash),
+               clone: Clone::clone(&orig.clone),
+               free: Clone::clone(&orig.free),
        }
 }
 impl Clone for SocketDescriptor {
index 7947ac628b0d34b0ad439fc484ddec49b501e204..b1421b83205d9e049fa014ab68c21e751becf87e 100644 (file)
@@ -254,7 +254,7 @@ pub extern "C" fn NetGraphMsgHandler_as_RoutingMessageHandler(this_arg: &NetGrap
                MessageSendEventsProvider: crate::util::events::MessageSendEventsProvider {
                        this_arg: unsafe { (*this_arg).inner as *mut c_void },
                        free: None,
-                       get_and_clear_pending_msg_events: NetGraphMsgHandler_RoutingMessageHandler_get_and_clear_pending_msg_events,
+                       get_and_clear_pending_msg_events: NetGraphMsgHandler_MessageSendEventsProvider_get_and_clear_pending_msg_events,
                },
        }
 }
@@ -320,12 +320,6 @@ extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_handle_query_short_channe
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::LightningError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() };
        local_ret
 }
-#[must_use]
-extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_get_and_clear_pending_msg_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_MessageSendEventZ {
-       let mut ret = <nativeNetGraphMsgHandler as lightning::util::events::MessageSendEventsProvider<>>::get_and_clear_pending_msg_events(unsafe { &mut *(this_arg as *mut nativeNetGraphMsgHandler) }, );
-       let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::util::events::MessageSendEvent::native_into(item) }); };
-       local_ret.into()
-}
 
 impl From<nativeNetGraphMsgHandler> for crate::util::events::MessageSendEventsProvider {
        fn from(obj: nativeNetGraphMsgHandler) -> Self {
index 72d9de5e899bdc2d6d5a8c42ce564e8f3b72dc78..295878e332524ae59a98ab82d3bcb30e2642c2ab 100644 (file)
@@ -42,16 +42,6 @@ pub enum Event {
                /// The value passed in to ChannelManager::create_channel
                user_channel_id: u64,
        },
-       /// Used to indicate that the client may now broadcast the funding transaction it created for a
-       /// channel. Broadcasting such a transaction prior to this event may lead to our counterparty
-       /// trivially stealing all funds in the funding transaction!
-       FundingBroadcastSafe {
-               /// The output, which was passed to ChannelManager::funding_transaction_generated, which is
-               /// now safe to broadcast.
-               funding_txo: crate::chain::transaction::OutPoint,
-               /// The value passed in to ChannelManager::create_channel
-               user_channel_id: u64,
-       },
        /// Indicates we've received money! Just gotta dig out that payment preimage and feed it to
        /// ChannelManager::claim_funds to get it....
        /// Note that if the preimage is not known or the amount paid is incorrect, you should call
@@ -137,14 +127,6 @@ impl Event {
                                        user_channel_id: user_channel_id_nonref,
                                }
                        },
-                       Event::FundingBroadcastSafe {ref funding_txo, ref user_channel_id, } => {
-                               let mut funding_txo_nonref = (*funding_txo).clone();
-                               let mut user_channel_id_nonref = (*user_channel_id).clone();
-                               nativeEvent::FundingBroadcastSafe {
-                                       funding_txo: *unsafe { Box::from_raw(funding_txo_nonref.take_inner()) },
-                                       user_channel_id: user_channel_id_nonref,
-                               }
-                       },
                        Event::PaymentReceived {ref payment_hash, ref payment_secret, ref amt, } => {
                                let mut payment_hash_nonref = (*payment_hash).clone();
                                let mut payment_secret_nonref = (*payment_secret).clone();
@@ -196,12 +178,6 @@ impl Event {
                                        user_channel_id: user_channel_id,
                                }
                        },
-                       Event::FundingBroadcastSafe {mut funding_txo, mut user_channel_id, } => {
-                               nativeEvent::FundingBroadcastSafe {
-                                       funding_txo: *unsafe { Box::from_raw(funding_txo.take_inner()) },
-                                       user_channel_id: user_channel_id,
-                               }
-                       },
                        Event::PaymentReceived {mut payment_hash, mut payment_secret, mut amt, } => {
                                let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret.data) }) };
                                nativeEvent::PaymentReceived {
@@ -249,14 +225,6 @@ impl Event {
                                        user_channel_id: user_channel_id_nonref,
                                }
                        },
-                       nativeEvent::FundingBroadcastSafe {ref funding_txo, ref user_channel_id, } => {
-                               let mut funding_txo_nonref = (*funding_txo).clone();
-                               let mut user_channel_id_nonref = (*user_channel_id).clone();
-                               Event::FundingBroadcastSafe {
-                                       funding_txo: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(funding_txo_nonref)), is_owned: true },
-                                       user_channel_id: user_channel_id_nonref,
-                               }
-                       },
                        nativeEvent::PaymentReceived {ref payment_hash, ref payment_secret, ref amt, } => {
                                let mut payment_hash_nonref = (*payment_hash).clone();
                                let mut payment_secret_nonref = (*payment_secret).clone();
@@ -308,12 +276,6 @@ impl Event {
                                        user_channel_id: user_channel_id,
                                }
                        },
-                       nativeEvent::FundingBroadcastSafe {mut funding_txo, mut user_channel_id, } => {
-                               Event::FundingBroadcastSafe {
-                                       funding_txo: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(funding_txo)), is_owned: true },
-                                       user_channel_id: user_channel_id,
-                               }
-                       },
                        nativeEvent::PaymentReceived {mut payment_hash, mut payment_secret, mut amt, } => {
                                let mut local_payment_secret = if payment_secret.is_none() { crate::c_types::ThirtyTwoBytes::null() } else {  { crate::c_types::ThirtyTwoBytes { data: (payment_secret.unwrap()).0 } } };
                                Event::PaymentReceived {