Merge pull request #748 from TheBlueMatt/2020-11-router-fuzzer
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Tue, 24 Nov 2020 16:36:14 +0000 (08:36 -0800)
committerGitHub <noreply@github.com>
Tue, 24 Nov 2020 16:36:14 +0000 (08:36 -0800)
Make router_target a bit easier for fuzzers to explore and fix two found bugs

37 files changed:
c-bindings-gen/src/main.rs
c-bindings-gen/src/types.rs
fuzz/src/chanmon_consistency.rs
genbindings.sh
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/c_types/derived.rs
lightning-c-bindings/src/c_types/mod.rs
lightning-c-bindings/src/chain/chaininterface.rs
lightning-c-bindings/src/chain/chainmonitor.rs
lightning-c-bindings/src/chain/channelmonitor.rs
lightning-c-bindings/src/chain/keysinterface.rs
lightning-c-bindings/src/chain/mod.rs
lightning-c-bindings/src/chain/transaction.rs
lightning-c-bindings/src/ln/chan_utils.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/routing/router.rs
lightning-c-bindings/src/util/config.rs
lightning-c-bindings/src/util/errors.rs
lightning-c-bindings/src/util/events.rs
lightning-c-bindings/src/util/logger.rs
lightning/src/chain/chainmonitor.rs
lightning/src/chain/channelmonitor.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/msgs.rs
lightning/src/ln/onchaintx.rs
lightning/src/routing/router.rs
lightning/src/util/events.rs

index ecbd947baa8fb7dfd72231ee39b73716632842a2..4193f6d36206c14bc47c3aa733b23b355f5e529e 100644 (file)
@@ -148,6 +148,9 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
        }
        writeln_docs(w, &t.attrs, "");
 
+       let mut gen_types = GenericTypes::new();
+       assert!(gen_types.learn_generics(&t.generics, types));
+
        writeln!(w, "#[repr(C)]\npub struct {} {{", trait_name).unwrap();
        writeln!(w, "\tpub this_arg: *mut c_void,").unwrap();
        let associated_types = learn_associated_types(t);
@@ -158,15 +161,17 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                match export_status(&m.attrs) {
                                        ExportStatus::NoExport => {
                                                // NoExport in this context means we'll hit an unimplemented!() at runtime,
-                                               // so add a comment noting that this needs to change in the output.
-                                               writeln!(w, "\t//XXX: Need to export {}", m.sig.ident).unwrap();
-                                               continue;
+                                               // so bail out.
+                                               unimplemented!();
                                        },
                                        ExportStatus::Export => {},
                                        ExportStatus::TestOnly => continue,
                                }
                                if m.default.is_some() { unimplemented!(); }
 
+                               gen_types.push_ctx();
+                               assert!(gen_types.learn_generics(&m.sig.generics, types));
+
                                writeln_docs(w, &m.attrs, "\t");
 
                                if let syn::ReturnType::Type(_, rtype) = &m.sig.output {
@@ -183,7 +188,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                // 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, None, false);
+                                               types.write_c_type(w, &*r.elem, Some(&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();
@@ -195,6 +200,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                // 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
@@ -204,8 +210,10 @@ 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, &associated_types, "c_void", types, None, true, false);
+                               write_method_params(w, &m.sig, &associated_types, "c_void", types, Some(&gen_types), true, false);
                                writeln!(w, ",").unwrap();
+
+                               gen_types.pop_ctx();
                        },
                        &syn::TraitItem::Type(_) => {},
                        _ => unimplemented!(),
@@ -218,7 +226,8 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                        generated_fields.push("clone".to_owned());
                },
                ("std::cmp::Eq", _) => {
-                       writeln!(w, "\tpub eq: extern \"C\" fn (this_arg: *const c_void, other_arg: *const c_void) -> bool,").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());
                },
                ("std::hash::Hash", _) => {
@@ -243,21 +252,25 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                ("std::cmp::Eq", _) => {
                        writeln!(w, "impl std::cmp::Eq for {} {{}}", trait_name).unwrap();
                        writeln!(w, "impl std::cmp::PartialEq for {} {{", trait_name).unwrap();
-                       writeln!(w, "\tfn eq(&self, o: &Self) -> bool {{ (self.eq)(self.this_arg, o.this_arg) }}\n}}").unwrap();
+                       writeln!(w, "\tfn eq(&self, o: &Self) -> bool {{ (self.eq)(self.this_arg, o) }}\n}}").unwrap();
                },
                ("std::hash::Hash", _) => {
                        writeln!(w, "impl std::hash::Hash for {} {{", trait_name).unwrap();
                        writeln!(w, "\tfn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {{ hasher.write_u64((self.hash)(self.this_arg)) }}\n}}").unwrap();
                },
                ("Clone", _) => {
-                       writeln!(w, "impl Clone for {} {{", trait_name).unwrap();
-                       writeln!(w, "\tfn clone(&self) -> Self {{").unwrap();
-                       writeln!(w, "\t\tSelf {{").unwrap();
-                       writeln!(w, "\t\tthis_arg: if let Some(f) = self.clone {{ (f)(self.this_arg) }} else {{ self.this_arg }},").unwrap();
+                       writeln!(w, "#[no_mangle]").unwrap();
+                       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\t{}: self.{}.clone(),", field, field).unwrap();
+                               writeln!(w, "\t\t{}: orig.{}.clone(),", field, field).unwrap();
                        }
-                       writeln!(w, "\t\t}}\n\t}}\n}}").unwrap();
+                       writeln!(w, "\t}}\n}}").unwrap();
+                       writeln!(w, "impl Clone for {} {{", trait_name).unwrap();
+                       writeln!(w, "\tfn clone(&self) -> Self {{").unwrap();
+                       writeln!(w, "\t\t{}_clone(self)", trait_name).unwrap();
+                       writeln!(w, "\t}}\n}}").unwrap();
                },
                (s, i) => {
                        if s != "util::events::MessageSendEventsProvider" { unimplemented!(); }
@@ -284,8 +297,10 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                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, m.sig.generics.params.iter());
+                               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 {
@@ -309,11 +324,11 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                                                        ident.mutability.is_some() || ident.subpat.is_some() {
                                                                                unimplemented!();
                                                                        }
-                                                                       write!(w, ", {}{}: ", if types.skip_arg(&*arg.ty, None) { "_" } else { "" }, ident.ident).unwrap();
+                                                                       write!(w, ", {}{}: ", if types.skip_arg(&*arg.ty, Some(&gen_types)) { "_" } else { "" }, ident.ident).unwrap();
                                                                }
                                                                _ => unimplemented!(),
                                                        }
-                                                       types.write_rust_type(w, &*arg.ty);
+                                                       types.write_rust_type(w, Some(&gen_types), &*arg.ty);
                                                }
                                        }
                                }
@@ -321,15 +336,14 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                match &m.sig.output {
                                        syn::ReturnType::Type(_, rtype) => {
                                                write!(w, " -> ").unwrap();
-                                               types.write_rust_type(w, &*rtype)
+                                               types.write_rust_type(w, Some(&gen_types), &*rtype)
                                        },
                                        _ => {},
                                }
                                write!(w, " {{\n\t\t").unwrap();
                                match export_status(&m.attrs) {
                                        ExportStatus::NoExport => {
-                                               writeln!(w, "unimplemented!();\n\t}}").unwrap();
-                                               continue;
+                                               unimplemented!();
                                        },
                                        _ => {},
                                }
@@ -339,25 +353,27 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                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, None);
+                                               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, None);
+                                               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, None, true);
+                               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, &associated_types, "\t", types, None, "", true);
+                               write_method_call_params(w, &m.sig, &associated_types, "\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, None)).unwrap();
+                                               writeln!(w, "\ttype {} = crate::{};", t.ident, types.resolve_path(&tr.path, Some(&gen_types))).unwrap();
                                        },
                                        _ => unimplemented!(),
                                }
@@ -439,6 +455,10 @@ fn writeln_opaque<W: std::io::Write>(w: &mut W, ident: &syn::Ident, struct_name:
                                                                        writeln!(w, "pub(crate) extern \"C\" fn {}_clone_void(this_ptr: *const c_void) -> *mut c_void {{", struct_name).unwrap();
                                                                        writeln!(w, "\tBox::into_raw(Box::new(unsafe {{ (*(this_ptr as *mut native{})).clone() }})) as *mut c_void", struct_name).unwrap();
                                                                        writeln!(w, "}}").unwrap();
+                                                                       writeln!(w, "#[no_mangle]").unwrap();
+                                                                       writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", struct_name, struct_name, struct_name).unwrap();
+                                                                       writeln!(w, "\t{} {{ inner: Box::into_raw(Box::new(unsafe {{ &*orig.inner }}.clone())), is_owned: true }}", struct_name).unwrap();
+                                                                       writeln!(w, "}}").unwrap();
                                                                        break 'attr_loop;
                                                                }
                                                        }
@@ -980,6 +1000,10 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type
        if needs_free {
                writeln!(w, "#[no_mangle]\npub extern \"C\" fn {}_free(this_ptr: {}) {{ }}", e.ident, e.ident).unwrap();
        }
+       writeln!(w, "#[no_mangle]").unwrap();
+       writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", e.ident, e.ident, e.ident).unwrap();
+       writeln!(w, "\torig.clone()").unwrap();
+       writeln!(w, "}}").unwrap();
        write_cpp_wrapper(cpp_headers, &format!("{}", e.ident), needs_free);
 }
 
index 3fc35e8b2558f8de6f7da2d4d017664a8b3390d1..483c1d9b9d12821b427cf8e0e143a56abb9a2400 100644 (file)
@@ -932,19 +932,34 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
        // *** Original Rust Type Printing ***
        // ***********************************
 
-       fn write_rust_path<W: std::io::Write>(&self, w: &mut W, path: &syn::Path) {
-               if let Some(resolved) = self.maybe_resolve_path(&path, None) {
+       fn in_rust_prelude(resolved_path: &str) -> bool {
+               match resolved_path {
+                       "Vec" => true,
+                       "Result" => true,
+                       "Option" => true,
+                       _ => false,
+               }
+       }
+
+       fn write_rust_path<W: std::io::Write>(&self, w: &mut W, generics_resolver: Option<&GenericTypes>, path: &syn::Path) {
+               if let Some(resolved) = self.maybe_resolve_path(&path, generics_resolver) {
                        if self.is_primitive(&resolved) {
                                write!(w, "{}", path.get_ident().unwrap()).unwrap();
                        } else {
-                               if resolved.starts_with("ln::") || resolved.starts_with("chain::") || resolved.starts_with("util::") {
-                                       write!(w, "lightning::{}", resolved).unwrap();
+                               // TODO: We should have a generic "is from a dependency" check here instead of
+                               // checking for "bitcoin" explicitly.
+                               if resolved.starts_with("bitcoin::") || Self::in_rust_prelude(&resolved) {
+                                       write!(w, "{}", resolved).unwrap();
+                               // If we're printing a generic argument, it needs to reference the crate, otherwise
+                               // the original crate:
+                               } else if self.maybe_resolve_path(&path, None).as_ref() == Some(&resolved) {
+                                       write!(w, "{}::{}", self.orig_crate, resolved).unwrap();
                                } else {
-                                       write!(w, "{}", resolved).unwrap(); // XXX: Probably doens't work, get_ident().unwrap()
+                                       write!(w, "crate::{}", resolved).unwrap();
                                }
                        }
                        if let syn::PathArguments::AngleBracketed(args) = &path.segments.iter().last().unwrap().arguments {
-                               self.write_rust_generic_arg(w, args.args.iter());
+                               self.write_rust_generic_arg(w, generics_resolver, args.args.iter());
                        }
                } else {
                        if path.leading_colon.is_some() {
@@ -954,12 +969,12 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                if idx != 0 { write!(w, "::").unwrap(); }
                                write!(w, "{}", seg.ident).unwrap();
                                if let syn::PathArguments::AngleBracketed(args) = &seg.arguments {
-                                       self.write_rust_generic_arg(w, args.args.iter());
+                                       self.write_rust_generic_arg(w, generics_resolver, args.args.iter());
                                }
                        }
                }
        }
-       pub fn write_rust_generic_param<'b, W: std::io::Write>(&self, w: &mut W, generics: impl Iterator<Item=&'b syn::GenericParam>) {
+       pub fn write_rust_generic_param<'b, W: std::io::Write>(&self, w: &mut W, generics_resolver: Option<&GenericTypes>, generics: impl Iterator<Item=&'b syn::GenericParam>) {
                let mut had_params = false;
                for (idx, arg) in generics.enumerate() {
                        if idx != 0 { write!(w, ", ").unwrap(); } else { write!(w, "<").unwrap(); }
@@ -974,7 +989,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                                match bound {
                                                        syn::TypeParamBound::Trait(tb) => {
                                                                if tb.paren_token.is_some() || tb.lifetimes.is_some() { unimplemented!(); }
-                                                               self.write_rust_path(w, &tb.path);
+                                                               self.write_rust_path(w, generics_resolver, &tb.path);
                                                        },
                                                        _ => unimplemented!(),
                                                }
@@ -987,24 +1002,24 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                if had_params { write!(w, ">").unwrap(); }
        }
 
-       pub fn write_rust_generic_arg<'b, W: std::io::Write>(&self, w: &mut W, generics: impl Iterator<Item=&'b syn::GenericArgument>) {
+       pub fn write_rust_generic_arg<'b, W: std::io::Write>(&self, w: &mut W, generics_resolver: Option<&GenericTypes>, generics: impl Iterator<Item=&'b syn::GenericArgument>) {
                write!(w, "<").unwrap();
                for (idx, arg) in generics.enumerate() {
                        if idx != 0 { write!(w, ", ").unwrap(); }
                        match arg {
-                               syn::GenericArgument::Type(t) => self.write_rust_type(w, t),
+                               syn::GenericArgument::Type(t) => self.write_rust_type(w, generics_resolver, t),
                                _ => unimplemented!(),
                        }
                }
                write!(w, ">").unwrap();
        }
-       pub fn write_rust_type<W: std::io::Write>(&self, w: &mut W, t: &syn::Type) {
+       pub fn write_rust_type<W: std::io::Write>(&self, w: &mut W, generics: Option<&GenericTypes>, t: &syn::Type) {
                match t {
                        syn::Type::Path(p) => {
                                if p.qself.is_some() || p.path.leading_colon.is_some() {
                                        unimplemented!();
                                }
-                               self.write_rust_path(w, &p.path);
+                               self.write_rust_path(w, generics, &p.path);
                        },
                        syn::Type::Reference(r) => {
                                write!(w, "&").unwrap();
@@ -1014,11 +1029,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                if r.mutability.is_some() {
                                        write!(w, "mut ").unwrap();
                                }
-                               self.write_rust_type(w, &*r.elem);
+                               self.write_rust_type(w, generics, &*r.elem);
                        },
                        syn::Type::Array(a) => {
                                write!(w, "[").unwrap();
-                               self.write_rust_type(w, &a.elem);
+                               self.write_rust_type(w, generics, &a.elem);
                                if let syn::Expr::Lit(l) = &a.len {
                                        if let syn::Lit::Int(i) = &l.lit {
                                                write!(w, "; {}]", i).unwrap();
@@ -1027,14 +1042,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        }
                        syn::Type::Slice(s) => {
                                write!(w, "[").unwrap();
-                               self.write_rust_type(w, &s.elem);
+                               self.write_rust_type(w, generics, &s.elem);
                                write!(w, "]").unwrap();
                        },
                        syn::Type::Tuple(s) => {
                                write!(w, "(").unwrap();
                                for (idx, t) in s.elems.iter().enumerate() {
                                        if idx != 0 { write!(w, ", ").unwrap(); }
-                                       self.write_rust_type(w, &t);
+                                       self.write_rust_type(w, generics, &t);
                                }
                                write!(w, ")").unwrap();
                        },
@@ -1743,7 +1758,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                        } else if in_crate {
                                                write!(w, "{}", c_type).unwrap();
                                        } else {
-                                               self.write_rust_type(w, &t);
+                                               self.write_rust_type(w, None, &t);
                                        }
                                } else {
                                        // If we just write out resolved_generic, it may mostly work, however for
index d88cc71fbf50a4175690d76a62bedfc5f3df808c..377ac8d7b5702c439e84dcc7b1db898645483428 100644 (file)
@@ -35,10 +35,11 @@ use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr,
 use lightning::chain::transaction::OutPoint;
 use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
 use lightning::chain::keysinterface::{KeysInterface, InMemoryChannelKeys};
-use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, ChannelManagerReadArgs};
+use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, ChannelManagerReadArgs};
 use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, UpdateAddHTLC, Init};
 use lightning::util::enforcing_trait_impls::EnforcingChannelKeys;
+use lightning::util::errors::APIError;
 use lightning::util::events;
 use lightning::util::logger::Logger;
 use lightning::util::config::UserConfig;
@@ -128,7 +129,7 @@ impl chain::Watch for TestChainMonitor {
                };
                let mut deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingChannelKeys>)>::
                        read(&mut Cursor::new(&map_entry.get().1)).unwrap().1;
-               deserialized_monitor.update_monitor(&update, &&TestBroadcaster {}, &self.logger).unwrap();
+               deserialized_monitor.update_monitor(&update, &&TestBroadcaster{}, &&FuzzEstimator{}, &self.logger).unwrap();
                let mut ser = VecWriter(Vec::new());
                deserialized_monitor.serialize_for_disk(&mut ser).unwrap();
                map_entry.insert((update.update_id, ser.0));
@@ -185,6 +186,93 @@ impl KeysInterface for KeyProvider {
        }
 }
 
+#[inline]
+fn check_api_err(api_err: APIError) {
+       match api_err {
+               APIError::APIMisuseError { .. } => panic!("We can't misuse the API"),
+               APIError::FeeRateTooHigh { .. } => panic!("We can't send too much fee?"),
+               APIError::RouteError { .. } => panic!("Our routes should work"),
+               APIError::ChannelUnavailable { err } => {
+                       // Test the error against a list of errors we can hit, and reject
+                       // all others. If you hit this panic, the list of acceptable errors
+                       // is probably just stale and you should add new messages here.
+                       match err.as_str() {
+                               "Peer for first hop currently disconnected/pending monitor update!" => {},
+                               _ if err.starts_with("Cannot push more than their max accepted HTLCs ") => {},
+                               _ if err.starts_with("Cannot send value that would put us over the max HTLC value in flight our peer will accept ") => {},
+                               _ if err.starts_with("Cannot send value that would put our balance under counterparty-announced channel reserve value") => {},
+                               _ if err.starts_with("Cannot send value that would overdraw remaining funds.") => {},
+                               _ if err.starts_with("Cannot send value that would not leave enough to pay for fees.") => {},
+                               _ => panic!(err),
+                       }
+               },
+               APIError::MonitorUpdateFailed => {
+                       // We can (obviously) temp-fail a monitor update
+               },
+       }
+}
+#[inline]
+fn check_payment_err(send_err: PaymentSendFailure) {
+       match send_err {
+               PaymentSendFailure::ParameterError(api_err) => check_api_err(api_err),
+               PaymentSendFailure::PathParameterError(per_path_results) => {
+                       for res in per_path_results { if let Err(api_err) = res { check_api_err(api_err); } }
+               },
+               PaymentSendFailure::AllFailedRetrySafe(per_path_results) => {
+                       for api_err in per_path_results { check_api_err(api_err); }
+               },
+               PaymentSendFailure::PartialFailure(per_path_results) => {
+                       for res in per_path_results { if let Err(api_err) = res { check_api_err(api_err); } }
+               },
+       }
+}
+
+type ChanMan = ChannelManager<EnforcingChannelKeys, Arc<TestChainMonitor>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>;
+
+#[inline]
+fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool {
+       let payment_hash = Sha256::hash(&[*payment_id; 1]);
+       *payment_id = payment_id.wrapping_add(1);
+       if let Err(err) = source.send_payment(&Route {
+               paths: vec![vec![RouteHop {
+                       pubkey: dest.get_our_node_id(),
+                       node_features: NodeFeatures::empty(),
+                       short_channel_id: dest_chan_id,
+                       channel_features: ChannelFeatures::empty(),
+                       fee_msat: amt,
+                       cltv_expiry_delta: 200,
+               }]],
+       }, PaymentHash(payment_hash.into_inner()), &None) {
+               check_payment_err(err);
+               false
+       } else { true }
+}
+#[inline]
+fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, dest: &ChanMan, dest_chan_id: u64, amt: u64, payment_id: &mut u8) -> bool {
+       let payment_hash = Sha256::hash(&[*payment_id; 1]);
+       *payment_id = payment_id.wrapping_add(1);
+       if let Err(err) = source.send_payment(&Route {
+               paths: vec![vec![RouteHop {
+                       pubkey: middle.get_our_node_id(),
+                       node_features: NodeFeatures::empty(),
+                       short_channel_id: middle_chan_id,
+                       channel_features: ChannelFeatures::empty(),
+                       fee_msat: 50000,
+                       cltv_expiry_delta: 100,
+               },RouteHop {
+                       pubkey: dest.get_our_node_id(),
+                       node_features: NodeFeatures::empty(),
+                       short_channel_id: dest_chan_id,
+                       channel_features: ChannelFeatures::empty(),
+                       fee_msat: amt,
+                       cltv_expiry_delta: 200,
+               }]],
+       }, PaymentHash(payment_hash.into_inner()), &None) {
+               check_payment_err(err);
+               false
+       } else { true }
+}
+
 #[inline]
 pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
        let fee_est = Arc::new(FuzzEstimator{});
@@ -200,7 +288,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                        config.channel_options.fee_proportional_millionths = 0;
                        config.channel_options.announced_channel = true;
                        config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
-                       (Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0)),
+                       (ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0),
                        monitor)
                } }
        }
@@ -237,14 +325,14 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                channel_monitors: monitor_refs,
                        };
 
-                       (<(BlockHash, ChannelManager<EnforcingChannelKeys, Arc<TestChainMonitor>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, chain_monitor)
+                       (<(BlockHash, ChanMan)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, chain_monitor)
                } }
        }
 
        let mut channel_txn = Vec::new();
        macro_rules! make_channel {
                ($source: expr, $dest: expr, $chan_id: expr) => { {
-                       $source.create_channel($dest.get_our_node_id(), 10000000, 42, 0, None).unwrap();
+                       $source.create_channel($dest.get_our_node_id(), 100_000, 42, 0, None).unwrap();
                        let open_channel = {
                                let events = $source.get_and_clear_pending_msg_events();
                                assert_eq!(events.len(), 1);
@@ -347,9 +435,9 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
 
        // 3 nodes is enough to hit all the possible cases, notably unknown-source-unknown-dest
        // forwarding.
-       let (mut node_a, mut monitor_a) = make_node!(0);
-       let (mut node_b, mut monitor_b) = make_node!(1);
-       let (mut node_c, mut monitor_c) = make_node!(2);
+       let (node_a, mut monitor_a) = make_node!(0);
+       let (node_b, mut monitor_b) = make_node!(1);
+       let (node_c, mut monitor_c) = make_node!(2);
 
        let mut nodes = [node_a, node_b, node_c];
 
@@ -365,7 +453,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
        let chan_a = nodes[0].list_usable_channels()[0].short_channel_id.unwrap();
        let chan_b = nodes[2].list_usable_channels()[0].short_channel_id.unwrap();
 
-       let mut payment_id = 0;
+       let mut payment_id: u8 = 0;
 
        let mut chan_a_disconnected = false;
        let mut chan_b_disconnected = false;
@@ -403,88 +491,44 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
        }
 
        loop {
-               macro_rules! send_payment {
-                       ($source: expr, $dest: expr, $amt: expr) => { {
-                               let payment_hash = Sha256::hash(&[payment_id; 1]);
-                               payment_id = payment_id.wrapping_add(1);
-                               if let Err(_) = $source.send_payment(&Route {
-                                       paths: vec![vec![RouteHop {
-                                               pubkey: $dest.0.get_our_node_id(),
-                                               node_features: NodeFeatures::empty(),
-                                               short_channel_id: $dest.1,
-                                               channel_features: ChannelFeatures::empty(),
-                                               fee_msat: $amt,
-                                               cltv_expiry_delta: 200,
-                                       }]],
-                               }, PaymentHash(payment_hash.into_inner()), &None) {
-                                       // Probably ran out of funds
-                                       test_return!();
-                               }
-                       } };
-                       ($source: expr, $middle: expr, $dest: expr, $amt: expr) => { {
-                               let payment_hash = Sha256::hash(&[payment_id; 1]);
-                               payment_id = payment_id.wrapping_add(1);
-                               if let Err(_) = $source.send_payment(&Route {
-                                       paths: vec![vec![RouteHop {
-                                               pubkey: $middle.0.get_our_node_id(),
-                                               node_features: NodeFeatures::empty(),
-                                               short_channel_id: $middle.1,
-                                               channel_features: ChannelFeatures::empty(),
-                                               fee_msat: 50000,
-                                               cltv_expiry_delta: 100,
-                                       },RouteHop {
-                                               pubkey: $dest.0.get_our_node_id(),
-                                               node_features: NodeFeatures::empty(),
-                                               short_channel_id: $dest.1,
-                                               channel_features: ChannelFeatures::empty(),
-                                               fee_msat: $amt,
-                                               cltv_expiry_delta: 200,
-                                       }]],
-                               }, PaymentHash(payment_hash.into_inner()), &None) {
-                                       // Probably ran out of funds
-                                       test_return!();
-                               }
-                       } }
-               }
                macro_rules! send_payment_with_secret {
                        ($source: expr, $middle: expr, $dest: expr) => { {
                                let payment_hash = Sha256::hash(&[payment_id; 1]);
                                payment_id = payment_id.wrapping_add(1);
                                let payment_secret = Sha256::hash(&[payment_id; 1]);
                                payment_id = payment_id.wrapping_add(1);
-                               if let Err(_) = $source.send_payment(&Route {
+                               if let Err(err) = $source.send_payment(&Route {
                                        paths: vec![vec![RouteHop {
                                                pubkey: $middle.0.get_our_node_id(),
                                                node_features: NodeFeatures::empty(),
                                                short_channel_id: $middle.1,
                                                channel_features: ChannelFeatures::empty(),
-                                               fee_msat: 50000,
+                                               fee_msat: 50_000,
                                                cltv_expiry_delta: 100,
                                        },RouteHop {
                                                pubkey: $dest.0.get_our_node_id(),
                                                node_features: NodeFeatures::empty(),
                                                short_channel_id: $dest.1,
                                                channel_features: ChannelFeatures::empty(),
-                                               fee_msat: 5000000,
+                                               fee_msat: 10_000_000,
                                                cltv_expiry_delta: 200,
                                        }],vec![RouteHop {
                                                pubkey: $middle.0.get_our_node_id(),
                                                node_features: NodeFeatures::empty(),
                                                short_channel_id: $middle.1,
                                                channel_features: ChannelFeatures::empty(),
-                                               fee_msat: 50000,
+                                               fee_msat: 50_000,
                                                cltv_expiry_delta: 100,
                                        },RouteHop {
                                                pubkey: $dest.0.get_our_node_id(),
                                                node_features: NodeFeatures::empty(),
                                                short_channel_id: $dest.1,
                                                channel_features: ChannelFeatures::empty(),
-                                               fee_msat: 5000000,
+                                               fee_msat: 10_000_000,
                                                cltv_expiry_delta: 200,
                                        }]],
                                }, PaymentHash(payment_hash.into_inner()), &Some(PaymentSecret(payment_secret.into_inner()))) {
-                                       // Probably ran out of funds
-                                       test_return!();
+                                       check_payment_err(err);
                                }
                        } }
                }
@@ -498,7 +542,9 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                        bc_events.clear();
                                        new_events
                                } else { Vec::new() };
+                               let mut had_events = false;
                                for event in events.iter().chain(nodes[$node].get_and_clear_pending_msg_events().iter()) {
+                                       had_events = true;
                                        match event {
                                                events::MessageSendEvent::UpdateHTLCs { ref node_id, updates: CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
                                                        for dest in nodes.iter() {
@@ -552,13 +598,10 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                                        // Can be generated due to a payment forward being rejected due to a
                                                        // channel having previously failed a monitor update
                                                },
-                                               events::MessageSendEvent::HandleError { action: ErrorAction::IgnoreError, .. } => {
-                                                       // Can be generated at any processing step to send back an error, disconnect
-                                                       // peer or just ignore
-                                               },
                                                _ => panic!("Unhandled message event"),
                                        }
                                }
+                               had_events
                        } }
                }
 
@@ -638,6 +681,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                                } else { Ordering::Equal }
                                        } else { Ordering::Equal }
                                });
+                               let had_events = !events.is_empty();
                                for event in events.drain(..) {
                                        match event {
                                                events::Event::PaymentReceived { payment_hash, payment_secret, amt } => {
@@ -657,43 +701,44 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                                _ => panic!("Unhandled event"),
                                        }
                                }
+                               had_events
                        } }
                }
 
                match get_slice!(1)[0] {
+                       // In general, we keep related message groups close together in binary form, allowing
+                       // bit-twiddling mutations to have similar effects. This is probably overkill, but no
+                       // harm in doing so.
+
                        0x00 => *monitor_a.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
                        0x01 => *monitor_b.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
                        0x02 => *monitor_c.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
-                       0x03 => *monitor_a.update_ret.lock().unwrap() = Ok(()),
-                       0x04 => *monitor_b.update_ret.lock().unwrap() = Ok(()),
-                       0x05 => *monitor_c.update_ret.lock().unwrap() = Ok(()),
-                       0x06 => {
+                       0x04 => *monitor_a.update_ret.lock().unwrap() = Ok(()),
+                       0x05 => *monitor_b.update_ret.lock().unwrap() = Ok(()),
+                       0x06 => *monitor_c.update_ret.lock().unwrap() = Ok(()),
+
+                       0x08 => {
                                if let Some((id, _)) = monitor_a.latest_monitors.lock().unwrap().get(&chan_1_funding) {
                                        nodes[0].channel_monitor_updated(&chan_1_funding, *id);
                                }
                        },
-                       0x07 => {
+                       0x09 => {
                                if let Some((id, _)) = monitor_b.latest_monitors.lock().unwrap().get(&chan_1_funding) {
                                        nodes[1].channel_monitor_updated(&chan_1_funding, *id);
                                }
                        },
-                       0x24 => {
+                       0x0a => {
                                if let Some((id, _)) = monitor_b.latest_monitors.lock().unwrap().get(&chan_2_funding) {
                                        nodes[1].channel_monitor_updated(&chan_2_funding, *id);
                                }
                        },
-                       0x08 => {
+                       0x0b => {
                                if let Some((id, _)) = monitor_c.latest_monitors.lock().unwrap().get(&chan_2_funding) {
                                        nodes[2].channel_monitor_updated(&chan_2_funding, *id);
                                }
                        },
-                       0x09 => send_payment!(nodes[0], (&nodes[1], chan_a), 5_000_000),
-                       0x0a => send_payment!(nodes[1], (&nodes[0], chan_a), 5_000_000),
-                       0x0b => send_payment!(nodes[1], (&nodes[2], chan_b), 5_000_000),
-                       0x0c => send_payment!(nodes[2], (&nodes[1], chan_b), 5_000_000),
-                       0x0d => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b), 5_000_000),
-                       0x0e => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a), 5_000_000),
-                       0x0f => {
+
+                       0x0c => {
                                if !chan_a_disconnected {
                                        nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
                                        nodes[1].peer_disconnected(&nodes[0].get_our_node_id(), false);
@@ -701,7 +746,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                        drain_msg_events_on_disconnect!(0);
                                }
                        },
-                       0x10 => {
+                       0x0d => {
                                if !chan_b_disconnected {
                                        nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false);
                                        nodes[2].peer_disconnected(&nodes[1].get_our_node_id(), false);
@@ -709,44 +754,45 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                        drain_msg_events_on_disconnect!(2);
                                }
                        },
-                       0x11 => {
+                       0x0e => {
                                if chan_a_disconnected {
                                        nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
                                        nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::empty() });
                                        chan_a_disconnected = false;
                                }
                        },
-                       0x12 => {
+                       0x0f => {
                                if chan_b_disconnected {
                                        nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::empty() });
                                        nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
                                        chan_b_disconnected = false;
                                }
                        },
-                       0x13 => process_msg_events!(0, true),
-                       0x14 => process_msg_events!(0, false),
-                       0x15 => process_events!(0, true),
-                       0x16 => process_events!(0, false),
-                       0x17 => process_msg_events!(1, true),
-                       0x18 => process_msg_events!(1, false),
-                       0x19 => process_events!(1, true),
-                       0x1a => process_events!(1, false),
-                       0x1b => process_msg_events!(2, true),
-                       0x1c => process_msg_events!(2, false),
-                       0x1d => process_events!(2, true),
-                       0x1e => process_events!(2, false),
-                       0x1f => {
+
+                       0x10 => { process_msg_events!(0, true); },
+                       0x11 => { process_msg_events!(0, false); },
+                       0x12 => { process_events!(0, true); },
+                       0x13 => { process_events!(0, false); },
+                       0x14 => { process_msg_events!(1, true); },
+                       0x15 => { process_msg_events!(1, false); },
+                       0x16 => { process_events!(1, true); },
+                       0x17 => { process_events!(1, false); },
+                       0x18 => { process_msg_events!(2, true); },
+                       0x19 => { process_msg_events!(2, false); },
+                       0x1a => { process_events!(2, true); },
+                       0x1b => { process_events!(2, false); },
+
+                       0x1c => {
                                if !chan_a_disconnected {
                                        nodes[1].peer_disconnected(&nodes[0].get_our_node_id(), false);
                                        chan_a_disconnected = true;
                                        drain_msg_events_on_disconnect!(0);
                                }
                                let (new_node_a, new_monitor_a) = reload_node!(node_a_ser, 0, monitor_a);
-                               node_a = Arc::new(new_node_a);
-                               nodes[0] = node_a.clone();
+                               nodes[0] = new_node_a;
                                monitor_a = new_monitor_a;
                        },
-                       0x20 => {
+                       0x1d => {
                                if !chan_a_disconnected {
                                        nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
                                        chan_a_disconnected = true;
@@ -760,42 +806,136 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                        bc_events.clear();
                                }
                                let (new_node_b, new_monitor_b) = reload_node!(node_b_ser, 1, monitor_b);
-                               node_b = Arc::new(new_node_b);
-                               nodes[1] = node_b.clone();
+                               nodes[1] = new_node_b;
                                monitor_b = new_monitor_b;
                        },
-                       0x21 => {
+                       0x1e => {
                                if !chan_b_disconnected {
                                        nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false);
                                        chan_b_disconnected = true;
                                        drain_msg_events_on_disconnect!(2);
                                }
                                let (new_node_c, new_monitor_c) = reload_node!(node_c_ser, 2, monitor_c);
-                               node_c = Arc::new(new_node_c);
-                               nodes[2] = node_c.clone();
+                               nodes[2] = new_node_c;
                                monitor_c = new_monitor_c;
                        },
-                       0x22 => send_payment_with_secret!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)),
-                       0x23 => send_payment_with_secret!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)),
-                       0x25 => send_payment!(nodes[0], (&nodes[1], chan_a), 10),
-                       0x26 => send_payment!(nodes[1], (&nodes[0], chan_a), 10),
-                       0x27 => send_payment!(nodes[1], (&nodes[2], chan_b), 10),
-                       0x28 => send_payment!(nodes[2], (&nodes[1], chan_b), 10),
-                       0x29 => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b), 10),
-                       0x2a => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a), 10),
-                       0x2b => send_payment!(nodes[0], (&nodes[1], chan_a), 1_000),
-                       0x2c => send_payment!(nodes[1], (&nodes[0], chan_a), 1_000),
-                       0x2d => send_payment!(nodes[1], (&nodes[2], chan_b), 1_000),
-                       0x2e => send_payment!(nodes[2], (&nodes[1], chan_b), 1_000),
-                       0x2f => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b), 1_000),
-                       0x30 => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a), 1_000),
-                       0x31 => send_payment!(nodes[0], (&nodes[1], chan_a), 100_000),
-                       0x32 => send_payment!(nodes[1], (&nodes[0], chan_a), 100_000),
-                       0x33 => send_payment!(nodes[1], (&nodes[2], chan_b), 100_000),
-                       0x34 => send_payment!(nodes[2], (&nodes[1], chan_b), 100_000),
-                       0x35 => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b), 100_000),
-                       0x36 => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a), 100_000),
-                       // 0x24 defined above
+
+                       // 1/10th the channel size:
+                       0x20 => { send_payment(&nodes[0], &nodes[1], chan_a, 10_000_000, &mut payment_id); },
+                       0x21 => { send_payment(&nodes[1], &nodes[0], chan_a, 10_000_000, &mut payment_id); },
+                       0x22 => { send_payment(&nodes[1], &nodes[2], chan_b, 10_000_000, &mut payment_id); },
+                       0x23 => { send_payment(&nodes[2], &nodes[1], chan_b, 10_000_000, &mut payment_id); },
+                       0x24 => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 10_000_000, &mut payment_id); },
+                       0x25 => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 10_000_000, &mut payment_id); },
+
+                       0x26 => { send_payment_with_secret!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)); },
+                       0x27 => { send_payment_with_secret!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)); },
+
+                       0x28 => { send_payment(&nodes[0], &nodes[1], chan_a, 1_000_000, &mut payment_id); },
+                       0x29 => { send_payment(&nodes[1], &nodes[0], chan_a, 1_000_000, &mut payment_id); },
+                       0x2a => { send_payment(&nodes[1], &nodes[2], chan_b, 1_000_000, &mut payment_id); },
+                       0x2b => { send_payment(&nodes[2], &nodes[1], chan_b, 1_000_000, &mut payment_id); },
+                       0x2c => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 1_000_000, &mut payment_id); },
+                       0x2d => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 1_000_000, &mut payment_id); },
+
+                       0x30 => { send_payment(&nodes[0], &nodes[1], chan_a, 100_000, &mut payment_id); },
+                       0x31 => { send_payment(&nodes[1], &nodes[0], chan_a, 100_000, &mut payment_id); },
+                       0x32 => { send_payment(&nodes[1], &nodes[2], chan_b, 100_000, &mut payment_id); },
+                       0x33 => { send_payment(&nodes[2], &nodes[1], chan_b, 100_000, &mut payment_id); },
+                       0x34 => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 100_000, &mut payment_id); },
+                       0x35 => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 100_000, &mut payment_id); },
+
+                       0x38 => { send_payment(&nodes[0], &nodes[1], chan_a, 10_000, &mut payment_id); },
+                       0x39 => { send_payment(&nodes[1], &nodes[0], chan_a, 10_000, &mut payment_id); },
+                       0x3a => { send_payment(&nodes[1], &nodes[2], chan_b, 10_000, &mut payment_id); },
+                       0x3b => { send_payment(&nodes[2], &nodes[1], chan_b, 10_000, &mut payment_id); },
+                       0x3c => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 10_000, &mut payment_id); },
+                       0x3d => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 10_000, &mut payment_id); },
+
+                       0x40 => { send_payment(&nodes[0], &nodes[1], chan_a, 1_000, &mut payment_id); },
+                       0x41 => { send_payment(&nodes[1], &nodes[0], chan_a, 1_000, &mut payment_id); },
+                       0x42 => { send_payment(&nodes[1], &nodes[2], chan_b, 1_000, &mut payment_id); },
+                       0x43 => { send_payment(&nodes[2], &nodes[1], chan_b, 1_000, &mut payment_id); },
+                       0x44 => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 1_000, &mut payment_id); },
+                       0x45 => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 1_000, &mut payment_id); },
+
+                       0x48 => { send_payment(&nodes[0], &nodes[1], chan_a, 100, &mut payment_id); },
+                       0x49 => { send_payment(&nodes[1], &nodes[0], chan_a, 100, &mut payment_id); },
+                       0x4a => { send_payment(&nodes[1], &nodes[2], chan_b, 100, &mut payment_id); },
+                       0x4b => { send_payment(&nodes[2], &nodes[1], chan_b, 100, &mut payment_id); },
+                       0x4c => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 100, &mut payment_id); },
+                       0x4d => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 100, &mut payment_id); },
+
+                       0x50 => { send_payment(&nodes[0], &nodes[1], chan_a, 10, &mut payment_id); },
+                       0x51 => { send_payment(&nodes[1], &nodes[0], chan_a, 10, &mut payment_id); },
+                       0x52 => { send_payment(&nodes[1], &nodes[2], chan_b, 10, &mut payment_id); },
+                       0x53 => { send_payment(&nodes[2], &nodes[1], chan_b, 10, &mut payment_id); },
+                       0x54 => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 10, &mut payment_id); },
+                       0x55 => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 10, &mut payment_id); },
+
+                       0x58 => { send_payment(&nodes[0], &nodes[1], chan_a, 1, &mut payment_id); },
+                       0x59 => { send_payment(&nodes[1], &nodes[0], chan_a, 1, &mut payment_id); },
+                       0x5a => { send_payment(&nodes[1], &nodes[2], chan_b, 1, &mut payment_id); },
+                       0x5b => { send_payment(&nodes[2], &nodes[1], chan_b, 1, &mut payment_id); },
+                       0x5c => { send_hop_payment(&nodes[0], &nodes[1], chan_a, &nodes[2], chan_b, 1, &mut payment_id); },
+                       0x5d => { send_hop_payment(&nodes[2], &nodes[1], chan_b, &nodes[0], chan_a, 1, &mut payment_id); },
+
+                       0xff => {
+                               // Test that no channel is in a stuck state where neither party can send funds even
+                               // after we resolve all pending events.
+                               // First make sure there are no pending monitor updates, resetting the error state
+                               // and calling channel_monitor_updated for each monitor.
+                               *monitor_a.update_ret.lock().unwrap() = Ok(());
+                               *monitor_b.update_ret.lock().unwrap() = Ok(());
+                               *monitor_c.update_ret.lock().unwrap() = Ok(());
+
+                               if let Some((id, _)) = monitor_a.latest_monitors.lock().unwrap().get(&chan_1_funding) {
+                                       nodes[0].channel_monitor_updated(&chan_1_funding, *id);
+                               }
+                               if let Some((id, _)) = monitor_b.latest_monitors.lock().unwrap().get(&chan_1_funding) {
+                                       nodes[1].channel_monitor_updated(&chan_1_funding, *id);
+                               }
+                               if let Some((id, _)) = monitor_b.latest_monitors.lock().unwrap().get(&chan_2_funding) {
+                                       nodes[1].channel_monitor_updated(&chan_2_funding, *id);
+                               }
+                               if let Some((id, _)) = monitor_c.latest_monitors.lock().unwrap().get(&chan_2_funding) {
+                                       nodes[2].channel_monitor_updated(&chan_2_funding, *id);
+                               }
+
+                               // Next, make sure peers are all connected to each other
+                               if chan_a_disconnected {
+                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
+                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::empty() });
+                                       chan_a_disconnected = false;
+                               }
+                               if chan_b_disconnected {
+                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::empty() });
+                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::empty() });
+                                       chan_b_disconnected = false;
+                               }
+
+                               for i in 0..std::usize::MAX {
+                                       if i == 100 { panic!("It may take may iterations to settle the state, but it should not take forever"); }
+                                       // Then, make sure any current forwards make their way to their destination
+                                       if process_msg_events!(0, false) { continue; }
+                                       if process_msg_events!(1, false) { continue; }
+                                       if process_msg_events!(2, false) { continue; }
+                                       // ...making sure any pending PendingHTLCsForwardable events are handled and
+                                       // payments claimed.
+                                       if process_events!(0, false) { continue; }
+                                       if process_events!(1, false) { continue; }
+                                       if process_events!(2, false) { continue; }
+                                       break;
+                               }
+
+                               // Finally, make sure that at least one end of each channel can make a substantial payment.
+                               assert!(
+                                       send_payment(&nodes[0], &nodes[1], chan_a, 10_000_000, &mut payment_id) ||
+                                       send_payment(&nodes[1], &nodes[0], chan_a, 10_000_000, &mut payment_id));
+                               assert!(
+                                       send_payment(&nodes[1], &nodes[2], chan_b, 10_000_000, &mut payment_id) ||
+                                       send_payment(&nodes[2], &nodes[1], chan_b, 10_000_000, &mut payment_id));
+                       },
                        _ => test_return!(),
                }
 
index 010296584482494c02fa008f23b236c59cd06da8..ae2a23578f05dd7fa5ec7d02de2452a0b97c92e4 100755 (executable)
@@ -167,7 +167,7 @@ else
 fi
 
 # Now build with LTO on on both C++ and rust, but without cross-language LTO:
-cargo rustc -v --release -- -C lto
+CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C lto
 clang++ -std=c++11 -Wall -flto -O2 -pthread demo.cpp target/release/libldk.a -ldl
 echo "C++ Bin size and runtime with only RL (LTO) optimized:"
 ls -lha a.out
@@ -179,7 +179,7 @@ if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then
        # or Ubuntu packages). This should work fine on Distros which do more involved
        # packaging than simply shipping the rustup binaries (eg Debian should Just Work
        # here).
-       cargo rustc -v --release -- -C linker-plugin-lto -C lto -C link-arg=-fuse-ld=lld
+       CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C linker-plugin-lto -C lto -C link-arg=-fuse-ld=lld
        $CLANGPP -Wall -std=c++11 -flto -fuse-ld=lld -O2 -pthread demo.cpp target/release/libldk.a -ldl
        echo "C++ Bin size and runtime with cross-language LTO:"
        ls -lha a.out
index ee1cedf17a12021adfb583425e306198a29568e1..531d7e679e522c38b59cb3285742765b40432bbb 100644 (file)
@@ -110,6 +110,12 @@ uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
        }
        // Note that we don't call _free() on target, but that's OK, its unitary
 }
+// We use the same fee estimator globally:
+const LDKFeeEstimator fee_est {
+       .this_arg = NULL,
+       .get_est_sat_per_1000_weight = get_fee,
+       .free = NULL,
+};
 
 static int num_txs_broadcasted = 0; // Technically a race, but ints are atomic on x86
 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
@@ -126,7 +132,7 @@ struct NodeMonitors {
        void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
                std::unique_lock<std::mutex> l(mut);
                for (auto& mon : mons) {
-                       LDK::CVec_C2Tuple_TxidCVec_TxOutZZZ res = ChannelMonitor_block_connected(&mon.second, &header_2, tx_data, height, broadcast, fee_est, *logger);
+                       LDK::CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ res = ChannelMonitor_block_connected(&mon.second, &header_2, tx_data, height, broadcast, fee_est, *logger);
                }
        }
 };
@@ -159,7 +165,7 @@ LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_
                        LDKBroadcasterInterface broadcaster = {
                                .broadcast_transaction = broadcast_tx,
                        };
-                       LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, update, &broadcaster, arg->logger);
+                       LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger);
                        assert(res->result_ok);
                }
        }
@@ -191,8 +197,8 @@ uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
 void sock_disconnect_socket(void *this_arg) {
        close((int)((long)this_arg));
 }
-bool sock_eq(const void *this_arg, const void *other_arg) {
-       return this_arg == other_arg;
+bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
+       return this_arg == other_arg->this_arg;
 }
 uint64_t sock_hash(const void *this_arg) {
        return (uint64_t)this_arg;
@@ -224,12 +230,6 @@ int main() {
        LDKNetwork network = LDKNetwork_Testnet;
 
        // Trait implementations:
-       LDKFeeEstimator fee_est {
-               .this_arg = NULL,
-               .get_est_sat_per_1000_weight = get_fee,
-               .free = NULL,
-       };
-
        LDKBroadcasterInterface broadcast {
                .this_arg = NULL,
                .broadcast_transaction = broadcast_tx,
@@ -420,19 +420,19 @@ int main() {
        }
 
        LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2TupleTempl_usize__Transaction*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
-       *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
+       *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
        ChannelManager_block_connected(&cm1, &channel_open_header, txdata, 1);
 
        txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2TupleTempl_usize__Transaction*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
-       *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
+       *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
        ChannelManager_block_connected(&cm2, &channel_open_header, txdata, 1);
 
        txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2TupleTempl_usize__Transaction*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
-       *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
+       *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
        mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
 
        txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2TupleTempl_usize__Transaction*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
-       *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
+       *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
        mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
 
        ChannelManager_block_connected(&cm1, &header_1, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, 2);
index cd246f92eafc6881e2c7c966a07d4d318c454092..45e4fa3ab6b72a601f0313dd0a9ced1816b233a0 100644 (file)
@@ -198,7 +198,10 @@ typedef enum LDKSecp256k1Error {
  * `data_is_owned` either set or unset at your discretion.
  */
 typedef struct LDKTransaction {
-   const uint8_t *data;
+   /**
+    * This is non-const for your convenience, an object passed to Rust is never written to.
+    */
+   uint8_t *data;
    uintptr_t datalen;
    bool data_is_owned;
 } LDKTransaction;
@@ -245,7 +248,7 @@ typedef LDKCResultTempl_u8__ChannelMonitorUpdateErr LDKCResult_NoneChannelMonito
  * inconsistent with the ChannelMonitor being called. eg for ChannelMonitor::update_monitor this
  * means you tried to update a monitor for a different channel or the ChannelMonitorUpdate was
  * corrupted.
- * Contains a human-readable error message.
+ * Contains a developer-readable error message.
  */
 typedef struct MUST_USE_STRUCT LDKMonitorUpdateError {
    /**
@@ -292,6 +295,13 @@ typedef struct LDKC2TupleTempl_OutPoint__CVec_u8Z {
 
 typedef LDKC2TupleTempl_OutPoint__CVec_u8Z LDKC2Tuple_OutPointScriptZ;
 
+typedef struct LDKC2TupleTempl_u32__TxOut {
+   uint32_t a;
+   LDKTxOut b;
+} LDKC2TupleTempl_u32__TxOut;
+
+typedef LDKC2TupleTempl_u32__TxOut LDKC2Tuple_u32TxOutZ;
+
 /**
  * Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
  * look up the corresponding function in rust-lightning's docs.
@@ -300,19 +310,19 @@ typedef struct LDKThirtyTwoBytes {
    uint8_t data[32];
 } LDKThirtyTwoBytes;
 
-typedef struct LDKCVecTempl_TxOut {
-   LDKTxOut *data;
+typedef struct LDKCVecTempl_C2TupleTempl_u32__TxOut {
+   LDKC2TupleTempl_u32__TxOut *data;
    uintptr_t datalen;
-} LDKCVecTempl_TxOut;
+} LDKCVecTempl_C2TupleTempl_u32__TxOut;
 
-typedef struct LDKC2TupleTempl_ThirtyTwoBytes__CVecTempl_TxOut {
+typedef struct LDKC2TupleTempl_ThirtyTwoBytes__CVecTempl_C2TupleTempl_u32__TxOut {
    LDKThirtyTwoBytes a;
-   LDKCVecTempl_TxOut b;
-} LDKC2TupleTempl_ThirtyTwoBytes__CVecTempl_TxOut;
+   LDKCVecTempl_C2TupleTempl_u32__TxOut b;
+} LDKC2TupleTempl_ThirtyTwoBytes__CVecTempl_C2TupleTempl_u32__TxOut;
 
-typedef LDKC2TupleTempl_ThirtyTwoBytes__CVecTempl_TxOut LDKC2Tuple_TxidCVec_TxOutZZ;
+typedef LDKC2TupleTempl_ThirtyTwoBytes__CVecTempl_C2TupleTempl_u32__TxOut LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ;
 
-typedef LDKCVecTempl_TxOut LDKCVec_TxOutZ;
+typedef LDKCVecTempl_C2TupleTempl_u32__TxOut LDKCVec_C2Tuple_u32TxOutZZ;
 
 typedef struct LDKC2TupleTempl_u64__u64 {
    uint64_t a;
@@ -1820,6 +1830,68 @@ typedef struct LDKFeeEstimator {
    void (*free)(void *this_arg);
 } LDKFeeEstimator;
 
+/**
+ * `Persist` defines behavior for persisting channel monitors: this could mean
+ * writing once to disk, and/or uploading to one or more backup services.
+ *
+ * Note that for every new monitor, you **must** persist the new `ChannelMonitor`
+ * to disk/backups. And, on every update, you **must** persist either the
+ * `ChannelMonitorUpdate` or the updated monitor itself. Otherwise, there is risk
+ * of situations such as revoking a transaction, then crashing before this
+ * revocation can be persisted, then unintentionally broadcasting a revoked
+ * transaction and losing money. This is a risk because previous channel states
+ * are toxic, so it's important that whatever channel state is persisted is
+ * kept up-to-date.
+ */
+typedef struct LDKPersist {
+   void *this_arg;
+   /**
+    * Persist a new channel's data. The data can be stored any way you want, but
+    * the identifier provided by Rust-Lightning is the channel's outpoint (and
+    * it is up to you to maintain a correct mapping between the outpoint and the
+    * stored channel data). Note that you **must** persist every new monitor to
+    * disk. See the `Persist` trait documentation for more details.
+    *
+    * See [`ChannelMonitor::serialize_for_disk`] for writing out a `ChannelMonitor`,
+    * and [`ChannelMonitorUpdateErr`] for requirements when returning errors.
+    *
+    * [`ChannelMonitor::serialize_for_disk`]: struct.ChannelMonitor.html#method.serialize_for_disk
+    * [`ChannelMonitorUpdateErr`]: enum.ChannelMonitorUpdateErr.html
+    */
+   LDKCResult_NoneChannelMonitorUpdateErrZ (*persist_new_channel)(const void *this_arg, LDKOutPoint id, const LDKChannelMonitor *data);
+   /**
+    * Update one channel's data. The provided `ChannelMonitor` has already
+    * applied the given update.
+    *
+    * Note that on every update, you **must** persist either the
+    * `ChannelMonitorUpdate` or the updated monitor itself to disk/backups. See
+    * the `Persist` trait documentation for more details.
+    *
+    * If an implementer chooses to persist the updates only, they need to make
+    * sure that all the updates are applied to the `ChannelMonitors` *before*
+    * the set of channel monitors is given to the `ChannelManager`
+    * deserialization routine. See [`ChannelMonitor::update_monitor`] for
+    * applying a monitor update to a monitor. If full `ChannelMonitors` are
+    * persisted, then there is no need to persist individual updates.
+    *
+    * Note that there could be a performance tradeoff between persisting complete
+    * channel monitors on every update vs. persisting only updates and applying
+    * them in batches. The size of each monitor grows `O(number of state updates)`
+    * whereas updates are small and `O(1)`.
+    *
+    * See [`ChannelMonitor::serialize_for_disk`] for writing out a `ChannelMonitor`,
+    * [`ChannelMonitorUpdate::write`] for writing out an update, and
+    * [`ChannelMonitorUpdateErr`] for requirements when returning errors.
+    *
+    * [`ChannelMonitor::update_monitor`]: struct.ChannelMonitor.html#impl-1
+    * [`ChannelMonitor::serialize_for_disk`]: struct.ChannelMonitor.html#method.serialize_for_disk
+    * [`ChannelMonitorUpdate::write`]: struct.ChannelMonitorUpdate.html#method.write
+    * [`ChannelMonitorUpdateErr`]: enum.ChannelMonitorUpdateErr.html
+    */
+   LDKCResult_NoneChannelMonitorUpdateErrZ (*update_persisted_channel)(const void *this_arg, LDKOutPoint id, const LDKChannelMonitorUpdate *update, const LDKChannelMonitor *data);
+   void (*free)(void *this_arg);
+} LDKPersist;
+
 
 
 /**
@@ -1875,12 +1947,12 @@ typedef struct LDKCVecTempl_Transaction {
 
 typedef LDKCVecTempl_Transaction LDKCVec_TransactionZ;
 
-typedef struct LDKCVecTempl_C2TupleTempl_ThirtyTwoBytes__CVecTempl_TxOut {
-   LDKC2TupleTempl_ThirtyTwoBytes__CVecTempl_TxOut *data;
+typedef struct LDKCVecTempl_C2TupleTempl_ThirtyTwoBytes__CVecTempl_C2TupleTempl_u32__TxOut {
+   LDKC2TupleTempl_ThirtyTwoBytes__CVecTempl_C2TupleTempl_u32__TxOut *data;
    uintptr_t datalen;
-} LDKCVecTempl_C2TupleTempl_ThirtyTwoBytes__CVecTempl_TxOut;
+} LDKCVecTempl_C2TupleTempl_ThirtyTwoBytes__CVecTempl_C2TupleTempl_u32__TxOut;
 
-typedef LDKCVecTempl_C2TupleTempl_ThirtyTwoBytes__CVecTempl_TxOut LDKCVec_C2Tuple_TxidCVec_TxOutZZZ;
+typedef LDKCVecTempl_C2TupleTempl_ThirtyTwoBytes__CVecTempl_C2TupleTempl_u32__TxOut LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ;
 
 typedef struct LDKSecretKey {
    uint8_t bytes[32];
@@ -2735,7 +2807,7 @@ typedef struct LDKSocketDescriptor {
     * socket_disconnected but prior to socket_disconnected returning.
     */
    void (*disconnect_socket)(void *this_arg);
-   bool (*eq)(const void *this_arg, const void *other_arg);
+   bool (*eq)(const void *this_arg, const LDKSocketDescriptor *other_arg);
    uint64_t (*hash)(const void *this_arg);
    void *(*clone)(const void *this_arg);
    void (*free)(void *this_arg);
@@ -3047,7 +3119,9 @@ extern const void (*C2Tuple_OutPointScriptZ_free)(LDKC2Tuple_OutPointScriptZ);
 
 extern const void (*C2Tuple_SignatureCVec_SignatureZZ_free)(LDKC2Tuple_SignatureCVec_SignatureZZ);
 
-extern const void (*C2Tuple_TxidCVec_TxOutZZ_free)(LDKC2Tuple_TxidCVec_TxOutZZ);
+extern const void (*C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_free)(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ);
+
+extern const void (*C2Tuple_u32TxOutZ_free)(LDKC2Tuple_u32TxOutZ);
 
 extern const void (*C2Tuple_u64u64Z_free)(LDKC2Tuple_u64u64Z);
 
@@ -3055,6 +3129,8 @@ extern const void (*C2Tuple_usizeTransactionZ_free)(LDKC2Tuple_usizeTransactionZ
 
 extern const void (*C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free)(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ);
 
+extern const uint64_t CLOSED_CHANNEL_UPDATE_ID;
+
 extern const void (*CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_free)(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ);
 
 extern const LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ (*CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_ok)(LDKC2Tuple_SignatureCVec_SignatureZZ);
@@ -3137,7 +3213,9 @@ extern const LDKCResult_boolPeerHandleErrorZ (*CResult_boolPeerHandleErrorZ_ok)(
 
 extern const void (*CVec_C2Tuple_HTLCOutputInCommitmentSignatureZZ_free)(LDKCVec_C2Tuple_HTLCOutputInCommitmentSignatureZZ);
 
-extern const void (*CVec_C2Tuple_TxidCVec_TxOutZZZ_free)(LDKCVec_C2Tuple_TxidCVec_TxOutZZZ);
+extern const void (*CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free)(LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ);
+
+extern const void (*CVec_C2Tuple_u32TxOutZZ_free)(LDKCVec_C2Tuple_u32TxOutZZ);
 
 extern const void (*CVec_C2Tuple_usizeTransactionZZ_free)(LDKCVec_C2Tuple_usizeTransactionZZ);
 
@@ -3173,8 +3251,6 @@ extern const void (*CVec_SpendableOutputDescriptorZ_free)(LDKCVec_SpendableOutpu
 
 extern const void (*CVec_TransactionZ_free)(LDKCVec_TransactionZ);
 
-extern const void (*CVec_TxOutZ_free)(LDKCVec_TxOutZ);
-
 extern const void (*CVec_UpdateAddHTLCZ_free)(LDKCVec_UpdateAddHTLCZ);
 
 extern const void (*CVec_UpdateFailHTLCZ_free)(LDKCVec_UpdateFailHTLCZ);
@@ -3201,7 +3277,9 @@ LDKCResult_NoneMonitorUpdateErrorZ CResult_NoneMonitorUpdateErrorZ_ok(void);
 
 LDKC2Tuple_OutPointScriptZ C2Tuple_OutPointScriptZ_new(LDKOutPoint a, LDKCVec_u8Z b);
 
-LDKC2Tuple_TxidCVec_TxOutZZ C2Tuple_TxidCVec_TxOutZZ_new(LDKThirtyTwoBytes a, LDKCVec_TxOutZ b);
+LDKC2Tuple_u32TxOutZ C2Tuple_u32TxOutZ_new(uint32_t a, LDKTxOut b);
+
+LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_new(LDKThirtyTwoBytes a, LDKCVec_C2Tuple_u32TxOutZZ b);
 
 LDKC2Tuple_u64u64Z C2Tuple_u64u64Z_new(uint64_t a, uint64_t b);
 
@@ -3225,8 +3303,12 @@ LDKC2Tuple_HTLCOutputInCommitmentSignatureZ C2Tuple_HTLCOutputInCommitmentSignat
 
 void Event_free(LDKEvent this_ptr);
 
+LDKEvent Event_clone(const LDKEvent *orig);
+
 void MessageSendEvent_free(LDKMessageSendEvent this_ptr);
 
+LDKMessageSendEvent MessageSendEvent_clone(const LDKMessageSendEvent *orig);
+
 /**
  * Calls the free function if one is set
  */
@@ -3239,6 +3321,10 @@ void EventsProvider_free(LDKEventsProvider this_ptr);
 
 void APIError_free(LDKAPIError this_ptr);
 
+LDKAPIError APIError_clone(const LDKAPIError *orig);
+
+LDKLevel Level_clone(const LDKLevel *orig);
+
 /**
  * Returns the most verbose logging level.
  */
@@ -3251,6 +3337,8 @@ void Logger_free(LDKLogger this_ptr);
 
 void ChannelHandshakeConfig_free(LDKChannelHandshakeConfig this_ptr);
 
+LDKChannelHandshakeConfig ChannelHandshakeConfig_clone(const LDKChannelHandshakeConfig *orig);
+
 /**
  * Confirmations we will wait for before considering the channel locked in.
  * Applied only for inbound channels (see ChannelHandshakeLimits::max_minimum_depth for the
@@ -3329,6 +3417,8 @@ MUST_USE_RES LDKChannelHandshakeConfig ChannelHandshakeConfig_default(void);
 
 void ChannelHandshakeLimits_free(LDKChannelHandshakeLimits this_ptr);
 
+LDKChannelHandshakeLimits ChannelHandshakeLimits_clone(const LDKChannelHandshakeLimits *orig);
+
 /**
  * Minimum allowed satoshis when a channel is funded, this is supplied by the sender and so
  * only applies to inbound channels.
@@ -3521,6 +3611,8 @@ MUST_USE_RES LDKChannelHandshakeLimits ChannelHandshakeLimits_default(void);
 
 void ChannelConfig_free(LDKChannelConfig this_ptr);
 
+LDKChannelConfig ChannelConfig_clone(const LDKChannelConfig *orig);
+
 /**
  * Amount (in millionths of a satoshi) the channel will charge per transferred satoshi.
  * This may be allowed to change at runtime in a later update, however doing so must result in
@@ -3609,6 +3701,8 @@ LDKChannelConfig ChannelConfig_read(LDKu8slice ser);
 
 void UserConfig_free(LDKUserConfig this_ptr);
 
+LDKUserConfig UserConfig_clone(const LDKUserConfig *orig);
+
 /**
  * Channel config that we propose to our counterparty.
  */
@@ -3643,6 +3737,8 @@ MUST_USE_RES LDKUserConfig UserConfig_new(LDKChannelHandshakeConfig own_channel_
 
 MUST_USE_RES LDKUserConfig UserConfig_default(void);
 
+LDKAccessError AccessError_clone(const LDKAccessError *orig);
+
 /**
  * Calls the free function if one is set
  */
@@ -3663,6 +3759,8 @@ void Filter_free(LDKFilter this_ptr);
  */
 void BroadcasterInterface_free(LDKBroadcasterInterface this_ptr);
 
+LDKConfirmationTarget ConfirmationTarget_clone(const LDKConfirmationTarget *orig);
+
 /**
  * Calls the free function if one is set
  */
@@ -3707,7 +3805,7 @@ void ChainMonitor_block_disconnected(const LDKChainMonitor *this_arg, const uint
  *
  * [`chain::Filter`]: ../trait.Filter.html
  */
-MUST_USE_RES LDKChainMonitor ChainMonitor_new(LDKFilter *chain_source, LDKBroadcasterInterface broadcaster, LDKLogger logger, LDKFeeEstimator feeest);
+MUST_USE_RES LDKChainMonitor ChainMonitor_new(LDKFilter *chain_source, LDKBroadcasterInterface broadcaster, LDKLogger logger, LDKFeeEstimator feeest, LDKPersist persister);
 
 LDKWatch ChainMonitor_as_Watch(const LDKChainMonitor *this_arg);
 
@@ -3715,25 +3813,39 @@ LDKEventsProvider ChainMonitor_as_EventsProvider(const LDKChainMonitor *this_arg
 
 void ChannelMonitorUpdate_free(LDKChannelMonitorUpdate this_ptr);
 
+LDKChannelMonitorUpdate ChannelMonitorUpdate_clone(const LDKChannelMonitorUpdate *orig);
+
 /**
  * The sequence number of this update. Updates *must* be replayed in-order according to this
  * sequence number (and updates may panic if they are not). The update_id values are strictly
- * increasing and increase by one for each new update.
+ * increasing and increase by one for each new update, with one exception specified below.
  *
  * This sequence number is also used to track up to which points updates which returned
  * ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
  * ChannelMonitor when ChannelManager::channel_monitor_updated is called.
+ *
+ * The only instance where update_id values are not strictly increasing is the case where we
+ * allow post-force-close updates with a special update ID of [`CLOSED_CHANNEL_UPDATE_ID`]. See
+ * its docs for more details.
+ *
+ * [`CLOSED_CHANNEL_UPDATE_ID`]: constant.CLOSED_CHANNEL_UPDATE_ID.html
  */
 uint64_t ChannelMonitorUpdate_get_update_id(const LDKChannelMonitorUpdate *this_ptr);
 
 /**
  * The sequence number of this update. Updates *must* be replayed in-order according to this
  * sequence number (and updates may panic if they are not). The update_id values are strictly
- * increasing and increase by one for each new update.
+ * increasing and increase by one for each new update, with one exception specified below.
  *
  * This sequence number is also used to track up to which points updates which returned
  * ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
  * ChannelMonitor when ChannelManager::channel_monitor_updated is called.
+ *
+ * The only instance where update_id values are not strictly increasing is the case where we
+ * allow post-force-close updates with a special update ID of [`CLOSED_CHANNEL_UPDATE_ID`]. See
+ * its docs for more details.
+ *
+ * [`CLOSED_CHANNEL_UPDATE_ID`]: constant.CLOSED_CHANNEL_UPDATE_ID.html
  */
 void ChannelMonitorUpdate_set_update_id(LDKChannelMonitorUpdate *this_ptr, uint64_t val);
 
@@ -3741,12 +3853,18 @@ LDKCVec_u8Z ChannelMonitorUpdate_write(const LDKChannelMonitorUpdate *obj);
 
 LDKChannelMonitorUpdate ChannelMonitorUpdate_read(LDKu8slice ser);
 
+LDKChannelMonitorUpdateErr ChannelMonitorUpdateErr_clone(const LDKChannelMonitorUpdateErr *orig);
+
 void MonitorUpdateError_free(LDKMonitorUpdateError this_ptr);
 
 void MonitorEvent_free(LDKMonitorEvent this_ptr);
 
+LDKMonitorEvent MonitorEvent_clone(const LDKMonitorEvent *orig);
+
 void HTLCUpdate_free(LDKHTLCUpdate this_ptr);
 
+LDKHTLCUpdate HTLCUpdate_clone(const LDKHTLCUpdate *orig);
+
 LDKCVec_u8Z HTLCUpdate_write(const LDKHTLCUpdate *obj);
 
 LDKHTLCUpdate HTLCUpdate_read(LDKu8slice ser);
@@ -3759,7 +3877,7 @@ void ChannelMonitor_free(LDKChannelMonitor this_ptr);
  *
  * panics if the given update is not the next update by update_id.
  */
-MUST_USE_RES LDKCResult_NoneMonitorUpdateErrorZ ChannelMonitor_update_monitor(LDKChannelMonitor *this_arg, LDKChannelMonitorUpdate updates, const LDKBroadcasterInterface *broadcaster, const LDKLogger *logger);
+MUST_USE_RES LDKCResult_NoneMonitorUpdateErrorZ ChannelMonitor_update_monitor(LDKChannelMonitor *this_arg, const LDKChannelMonitorUpdate *updates, const LDKBroadcasterInterface *broadcaster, const LDKFeeEstimator *fee_estimator, const LDKLogger *logger);
 
 /**
  * Gets the update_id from the latest ChannelMonitorUpdate which was applied to this
@@ -3816,7 +3934,7 @@ MUST_USE_RES LDKCVec_TransactionZ ChannelMonitor_get_latest_holder_commitment_tx
  *
  * [`get_outputs_to_watch`]: #method.get_outputs_to_watch
  */
-MUST_USE_RES LDKCVec_C2Tuple_TxidCVec_TxOutZZZ ChannelMonitor_block_connected(LDKChannelMonitor *this_arg, const uint8_t (*header)[80], LDKCVec_C2Tuple_usizeTransactionZZ txdata, uint32_t height, LDKBroadcasterInterface broadcaster, LDKFeeEstimator fee_estimator, LDKLogger logger);
+MUST_USE_RES LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ ChannelMonitor_block_connected(LDKChannelMonitor *this_arg, const uint8_t (*header)[80], LDKCVec_C2Tuple_usizeTransactionZZ txdata, uint32_t height, LDKBroadcasterInterface broadcaster, LDKFeeEstimator fee_estimator, LDKLogger logger);
 
 /**
  * Determines if the disconnected block contained any transactions of interest and updates
@@ -3824,8 +3942,15 @@ MUST_USE_RES LDKCVec_C2Tuple_TxidCVec_TxOutZZZ ChannelMonitor_block_connected(LD
  */
 void ChannelMonitor_block_disconnected(LDKChannelMonitor *this_arg, const uint8_t (*header)[80], uint32_t height, LDKBroadcasterInterface broadcaster, LDKFeeEstimator fee_estimator, LDKLogger logger);
 
+/**
+ * Calls the free function if one is set
+ */
+void Persist_free(LDKPersist this_ptr);
+
 void OutPoint_free(LDKOutPoint this_ptr);
 
+LDKOutPoint OutPoint_clone(const LDKOutPoint *orig);
+
 /**
  * The referenced transaction's txid.
  */
@@ -3859,6 +3984,10 @@ LDKOutPoint OutPoint_read(LDKu8slice ser);
 
 void SpendableOutputDescriptor_free(LDKSpendableOutputDescriptor this_ptr);
 
+LDKSpendableOutputDescriptor SpendableOutputDescriptor_clone(const LDKSpendableOutputDescriptor *orig);
+
+LDKChannelKeys ChannelKeys_clone(const LDKChannelKeys *orig);
+
 /**
  * Calls the free function if one is set
  */
@@ -3871,6 +4000,8 @@ void KeysInterface_free(LDKKeysInterface this_ptr);
 
 void InMemoryChannelKeys_free(LDKInMemoryChannelKeys this_ptr);
 
+LDKInMemoryChannelKeys InMemoryChannelKeys_clone(const LDKInMemoryChannelKeys *orig);
+
 /**
  * Private key of anchor tx
  */
@@ -4005,6 +4136,8 @@ void ChannelManager_free(LDKChannelManager this_ptr);
 
 void ChannelDetails_free(LDKChannelDetails this_ptr);
 
+LDKChannelDetails ChannelDetails_clone(const LDKChannelDetails *orig);
+
 /**
  * The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
  * thereafter this is the txid of the funding transaction xor the funding transaction output).
@@ -4444,8 +4577,12 @@ void DecodeError_free(LDKDecodeError this_ptr);
 
 void Init_free(LDKInit this_ptr);
 
+LDKInit Init_clone(const LDKInit *orig);
+
 void ErrorMessage_free(LDKErrorMessage this_ptr);
 
+LDKErrorMessage ErrorMessage_clone(const LDKErrorMessage *orig);
+
 /**
  * The channel ID involved in the error
  */
@@ -4476,6 +4613,8 @@ MUST_USE_RES LDKErrorMessage ErrorMessage_new(LDKThirtyTwoBytes channel_id_arg,
 
 void Ping_free(LDKPing this_ptr);
 
+LDKPing Ping_clone(const LDKPing *orig);
+
 /**
  * The desired response length
  */
@@ -4502,6 +4641,8 @@ MUST_USE_RES LDKPing Ping_new(uint16_t ponglen_arg, uint16_t byteslen_arg);
 
 void Pong_free(LDKPong this_ptr);
 
+LDKPong Pong_clone(const LDKPong *orig);
+
 /**
  * The pong packet size.
  * This field is not sent on the wire. byteslen zeros are sent.
@@ -4518,6 +4659,8 @@ MUST_USE_RES LDKPong Pong_new(uint16_t byteslen_arg);
 
 void OpenChannel_free(LDKOpenChannel this_ptr);
 
+LDKOpenChannel OpenChannel_clone(const LDKOpenChannel *orig);
+
 /**
  * The genesis hash of the blockchain where the channel is to be opened
  */
@@ -4700,6 +4843,8 @@ void OpenChannel_set_channel_flags(LDKOpenChannel *this_ptr, uint8_t val);
 
 void AcceptChannel_free(LDKAcceptChannel this_ptr);
 
+LDKAcceptChannel AcceptChannel_clone(const LDKAcceptChannel *orig);
+
 /**
  * A temporary channel ID, until the funding outpoint is announced
  */
@@ -4842,6 +4987,8 @@ void AcceptChannel_set_first_per_commitment_point(LDKAcceptChannel *this_ptr, LD
 
 void FundingCreated_free(LDKFundingCreated this_ptr);
 
+LDKFundingCreated FundingCreated_clone(const LDKFundingCreated *orig);
+
 /**
  * A temporary channel ID, until the funding is established
  */
@@ -4886,6 +5033,8 @@ MUST_USE_RES LDKFundingCreated FundingCreated_new(LDKThirtyTwoBytes temporary_ch
 
 void FundingSigned_free(LDKFundingSigned this_ptr);
 
+LDKFundingSigned FundingSigned_clone(const LDKFundingSigned *orig);
+
 /**
  * The channel ID
  */
@@ -4910,6 +5059,8 @@ MUST_USE_RES LDKFundingSigned FundingSigned_new(LDKThirtyTwoBytes channel_id_arg
 
 void FundingLocked_free(LDKFundingLocked this_ptr);
 
+LDKFundingLocked FundingLocked_clone(const LDKFundingLocked *orig);
+
 /**
  * The channel ID
  */
@@ -4934,6 +5085,8 @@ MUST_USE_RES LDKFundingLocked FundingLocked_new(LDKThirtyTwoBytes channel_id_arg
 
 void Shutdown_free(LDKShutdown this_ptr);
 
+LDKShutdown Shutdown_clone(const LDKShutdown *orig);
+
 /**
  * The channel ID
  */
@@ -4960,6 +5113,8 @@ MUST_USE_RES LDKShutdown Shutdown_new(LDKThirtyTwoBytes channel_id_arg, LDKCVec_
 
 void ClosingSigned_free(LDKClosingSigned this_ptr);
 
+LDKClosingSigned ClosingSigned_clone(const LDKClosingSigned *orig);
+
 /**
  * The channel ID
  */
@@ -4994,6 +5149,8 @@ MUST_USE_RES LDKClosingSigned ClosingSigned_new(LDKThirtyTwoBytes channel_id_arg
 
 void UpdateAddHTLC_free(LDKUpdateAddHTLC this_ptr);
 
+LDKUpdateAddHTLC UpdateAddHTLC_clone(const LDKUpdateAddHTLC *orig);
+
 /**
  * The channel ID
  */
@@ -5046,6 +5203,8 @@ void UpdateAddHTLC_set_cltv_expiry(LDKUpdateAddHTLC *this_ptr, uint32_t val);
 
 void UpdateFulfillHTLC_free(LDKUpdateFulfillHTLC this_ptr);
 
+LDKUpdateFulfillHTLC UpdateFulfillHTLC_clone(const LDKUpdateFulfillHTLC *orig);
+
 /**
  * The channel ID
  */
@@ -5080,6 +5239,8 @@ MUST_USE_RES LDKUpdateFulfillHTLC UpdateFulfillHTLC_new(LDKThirtyTwoBytes channe
 
 void UpdateFailHTLC_free(LDKUpdateFailHTLC this_ptr);
 
+LDKUpdateFailHTLC UpdateFailHTLC_clone(const LDKUpdateFailHTLC *orig);
+
 /**
  * The channel ID
  */
@@ -5102,6 +5263,8 @@ void UpdateFailHTLC_set_htlc_id(LDKUpdateFailHTLC *this_ptr, uint64_t val);
 
 void UpdateFailMalformedHTLC_free(LDKUpdateFailMalformedHTLC this_ptr);
 
+LDKUpdateFailMalformedHTLC UpdateFailMalformedHTLC_clone(const LDKUpdateFailMalformedHTLC *orig);
+
 /**
  * The channel ID
  */
@@ -5134,6 +5297,8 @@ void UpdateFailMalformedHTLC_set_failure_code(LDKUpdateFailMalformedHTLC *this_p
 
 void CommitmentSigned_free(LDKCommitmentSigned this_ptr);
 
+LDKCommitmentSigned CommitmentSigned_clone(const LDKCommitmentSigned *orig);
+
 /**
  * The channel ID
  */
@@ -5163,6 +5328,8 @@ MUST_USE_RES LDKCommitmentSigned CommitmentSigned_new(LDKThirtyTwoBytes channel_
 
 void RevokeAndACK_free(LDKRevokeAndACK this_ptr);
 
+LDKRevokeAndACK RevokeAndACK_clone(const LDKRevokeAndACK *orig);
+
 /**
  * The channel ID
  */
@@ -5197,6 +5364,8 @@ MUST_USE_RES LDKRevokeAndACK RevokeAndACK_new(LDKThirtyTwoBytes channel_id_arg,
 
 void UpdateFee_free(LDKUpdateFee this_ptr);
 
+LDKUpdateFee UpdateFee_clone(const LDKUpdateFee *orig);
+
 /**
  * The channel ID
  */
@@ -5221,6 +5390,8 @@ MUST_USE_RES LDKUpdateFee UpdateFee_new(LDKThirtyTwoBytes channel_id_arg, uint32
 
 void DataLossProtect_free(LDKDataLossProtect this_ptr);
 
+LDKDataLossProtect DataLossProtect_clone(const LDKDataLossProtect *orig);
+
 /**
  * Proof that the sender knows the per-commitment secret of a specific commitment transaction
  * belonging to the recipient
@@ -5247,6 +5418,8 @@ MUST_USE_RES LDKDataLossProtect DataLossProtect_new(LDKThirtyTwoBytes your_last_
 
 void ChannelReestablish_free(LDKChannelReestablish this_ptr);
 
+LDKChannelReestablish ChannelReestablish_clone(const LDKChannelReestablish *orig);
+
 /**
  * The channel ID
  */
@@ -5279,6 +5452,8 @@ void ChannelReestablish_set_next_remote_commitment_number(LDKChannelReestablish
 
 void AnnouncementSignatures_free(LDKAnnouncementSignatures this_ptr);
 
+LDKAnnouncementSignatures AnnouncementSignatures_clone(const LDKAnnouncementSignatures *orig);
+
 /**
  * The channel ID
  */
@@ -5323,8 +5498,12 @@ MUST_USE_RES LDKAnnouncementSignatures AnnouncementSignatures_new(LDKThirtyTwoBy
 
 void NetAddress_free(LDKNetAddress this_ptr);
 
+LDKNetAddress NetAddress_clone(const LDKNetAddress *orig);
+
 void UnsignedNodeAnnouncement_free(LDKUnsignedNodeAnnouncement this_ptr);
 
+LDKUnsignedNodeAnnouncement UnsignedNodeAnnouncement_clone(const LDKUnsignedNodeAnnouncement *orig);
+
 /**
  * The advertised features
  */
@@ -5386,6 +5565,8 @@ void UnsignedNodeAnnouncement_set_addresses(LDKUnsignedNodeAnnouncement *this_pt
 
 void NodeAnnouncement_free(LDKNodeAnnouncement this_ptr);
 
+LDKNodeAnnouncement NodeAnnouncement_clone(const LDKNodeAnnouncement *orig);
+
 /**
  * The signature by the node key
  */
@@ -5410,6 +5591,8 @@ MUST_USE_RES LDKNodeAnnouncement NodeAnnouncement_new(LDKSignature signature_arg
 
 void UnsignedChannelAnnouncement_free(LDKUnsignedChannelAnnouncement this_ptr);
 
+LDKUnsignedChannelAnnouncement UnsignedChannelAnnouncement_clone(const LDKUnsignedChannelAnnouncement *orig);
+
 /**
  * The advertised channel features
  */
@@ -5482,6 +5665,8 @@ void UnsignedChannelAnnouncement_set_bitcoin_key_2(LDKUnsignedChannelAnnouncemen
 
 void ChannelAnnouncement_free(LDKChannelAnnouncement this_ptr);
 
+LDKChannelAnnouncement ChannelAnnouncement_clone(const LDKChannelAnnouncement *orig);
+
 /**
  * Authentication of the announcement by the first public node
  */
@@ -5536,6 +5721,8 @@ MUST_USE_RES LDKChannelAnnouncement ChannelAnnouncement_new(LDKSignature node_si
 
 void UnsignedChannelUpdate_free(LDKUnsignedChannelUpdate this_ptr);
 
+LDKUnsignedChannelUpdate UnsignedChannelUpdate_clone(const LDKUnsignedChannelUpdate *orig);
+
 /**
  * The genesis hash of the blockchain where the channel is to be opened
  */
@@ -5618,6 +5805,8 @@ void UnsignedChannelUpdate_set_fee_proportional_millionths(LDKUnsignedChannelUpd
 
 void ChannelUpdate_free(LDKChannelUpdate this_ptr);
 
+LDKChannelUpdate ChannelUpdate_clone(const LDKChannelUpdate *orig);
+
 /**
  * A signature of the channel update
  */
@@ -5642,6 +5831,8 @@ MUST_USE_RES LDKChannelUpdate ChannelUpdate_new(LDKSignature signature_arg, LDKU
 
 void QueryChannelRange_free(LDKQueryChannelRange this_ptr);
 
+LDKQueryChannelRange QueryChannelRange_clone(const LDKQueryChannelRange *orig);
+
 /**
  * The genesis hash of the blockchain being queried
  */
@@ -5676,6 +5867,8 @@ MUST_USE_RES LDKQueryChannelRange QueryChannelRange_new(LDKThirtyTwoBytes chain_
 
 void ReplyChannelRange_free(LDKReplyChannelRange this_ptr);
 
+LDKReplyChannelRange ReplyChannelRange_clone(const LDKReplyChannelRange *orig);
+
 /**
  * The genesis hash of the blockchain being queried
  */
@@ -5727,6 +5920,8 @@ MUST_USE_RES LDKReplyChannelRange ReplyChannelRange_new(LDKThirtyTwoBytes chain_
 
 void QueryShortChannelIds_free(LDKQueryShortChannelIds this_ptr);
 
+LDKQueryShortChannelIds QueryShortChannelIds_clone(const LDKQueryShortChannelIds *orig);
+
 /**
  * The genesis hash of the blockchain being queried
  */
@@ -5746,6 +5941,8 @@ MUST_USE_RES LDKQueryShortChannelIds QueryShortChannelIds_new(LDKThirtyTwoBytes
 
 void ReplyShortChannelIdsEnd_free(LDKReplyShortChannelIdsEnd this_ptr);
 
+LDKReplyShortChannelIdsEnd ReplyShortChannelIdsEnd_clone(const LDKReplyShortChannelIdsEnd *orig);
+
 /**
  * The genesis hash of the blockchain that was queried
  */
@@ -5772,6 +5969,8 @@ MUST_USE_RES LDKReplyShortChannelIdsEnd ReplyShortChannelIdsEnd_new(LDKThirtyTwo
 
 void GossipTimestampFilter_free(LDKGossipTimestampFilter this_ptr);
 
+LDKGossipTimestampFilter GossipTimestampFilter_clone(const LDKGossipTimestampFilter *orig);
+
 /**
  * The genesis hash of the blockchain for channel and node information
  */
@@ -5806,6 +6005,8 @@ MUST_USE_RES LDKGossipTimestampFilter GossipTimestampFilter_new(LDKThirtyTwoByte
 
 void ErrorAction_free(LDKErrorAction this_ptr);
 
+LDKErrorAction ErrorAction_clone(const LDKErrorAction *orig);
+
 void LightningError_free(LDKLightningError this_ptr);
 
 /**
@@ -5832,6 +6033,8 @@ MUST_USE_RES LDKLightningError LightningError_new(LDKCVec_u8Z err_arg, LDKErrorA
 
 void CommitmentUpdate_free(LDKCommitmentUpdate this_ptr);
 
+LDKCommitmentUpdate CommitmentUpdate_clone(const LDKCommitmentUpdate *orig);
+
 /**
  * update_add_htlc messages which should be sent
  */
@@ -5876,6 +6079,8 @@ MUST_USE_RES LDKCommitmentUpdate CommitmentUpdate_new(LDKCVec_UpdateAddHTLCZ upd
 
 void HTLCFailChannelUpdate_free(LDKHTLCFailChannelUpdate this_ptr);
 
+LDKHTLCFailChannelUpdate HTLCFailChannelUpdate_clone(const LDKHTLCFailChannelUpdate *orig);
+
 /**
  * Calls the free function if one is set
  */
@@ -6038,6 +6243,8 @@ void MessageHandler_set_route_handler(LDKMessageHandler *this_ptr, LDKRoutingMes
 
 MUST_USE_RES LDKMessageHandler MessageHandler_new(LDKChannelMessageHandler chan_handler_arg, LDKRoutingMessageHandler route_handler_arg);
 
+LDKSocketDescriptor SocketDescriptor_clone(const LDKSocketDescriptor *orig);
+
 /**
  * Calls the free function if one is set
  */
@@ -6212,6 +6419,8 @@ LDKCResult_PublicKeySecpErrorZ derive_public_revocation_key(LDKPublicKey per_com
 
 void TxCreationKeys_free(LDKTxCreationKeys this_ptr);
 
+LDKTxCreationKeys TxCreationKeys_clone(const LDKTxCreationKeys *orig);
+
 /**
  * The broadcaster's per-commitment public key which was used to derive the other keys.
  */
@@ -6274,6 +6483,8 @@ LDKTxCreationKeys TxCreationKeys_read(LDKu8slice ser);
 
 void PreCalculatedTxCreationKeys_free(LDKPreCalculatedTxCreationKeys this_ptr);
 
+LDKPreCalculatedTxCreationKeys PreCalculatedTxCreationKeys_clone(const LDKPreCalculatedTxCreationKeys *orig);
+
 /**
  * Create a new PreCalculatedTxCreationKeys from TxCreationKeys
  */
@@ -6292,6 +6503,8 @@ MUST_USE_RES LDKPublicKey PreCalculatedTxCreationKeys_per_commitment_point(const
 
 void ChannelPublicKeys_free(LDKChannelPublicKeys this_ptr);
 
+LDKChannelPublicKeys ChannelPublicKeys_clone(const LDKChannelPublicKeys *orig);
+
 /**
  * The public key which is used to sign all commitment transactions, as it appears in the
  * on-chain channel lock-in 2-of-2 multisig output.
@@ -6380,6 +6593,8 @@ LDKCVec_u8Z get_revokeable_redeemscript(LDKPublicKey revocation_key, uint16_t co
 
 void HTLCOutputInCommitment_free(LDKHTLCOutputInCommitment this_ptr);
 
+LDKHTLCOutputInCommitment HTLCOutputInCommitment_clone(const LDKHTLCOutputInCommitment *orig);
+
 /**
  * Whether the HTLC was \"offered\" (ie outbound in relation to this commitment transaction).
  * Note that this is not the same as whether it is ountbound *from us*. To determine that you
@@ -6451,6 +6666,8 @@ LDKTransaction build_htlc_transaction(const uint8_t (*prev_hash)[32], uint32_t f
 
 void HolderCommitmentTransaction_free(LDKHolderCommitmentTransaction this_ptr);
 
+LDKHolderCommitmentTransaction HolderCommitmentTransaction_clone(const LDKHolderCommitmentTransaction *orig);
+
 /**
  * The commitment transaction itself, in unsigned form.
  */
@@ -6550,6 +6767,8 @@ void ChannelFeatures_free(LDKChannelFeatures this_ptr);
 
 void RouteHop_free(LDKRouteHop this_ptr);
 
+LDKRouteHop RouteHop_clone(const LDKRouteHop *orig);
+
 /**
  * The node_id of the node at this hop.
  */
@@ -6620,6 +6839,8 @@ MUST_USE_RES LDKRouteHop RouteHop_new(LDKPublicKey pubkey_arg, LDKNodeFeatures n
 
 void Route_free(LDKRoute this_ptr);
 
+LDKRoute Route_clone(const LDKRoute *orig);
+
 /**
  * The list of routes taken for a single (potentially-)multi-part payment. The pubkey of the
  * last RouteHop in each path must be the same.
@@ -6638,6 +6859,8 @@ LDKRoute Route_read(LDKu8slice ser);
 
 void RouteHint_free(LDKRouteHint this_ptr);
 
+LDKRouteHint RouteHint_clone(const LDKRouteHint *orig);
+
 /**
  * The node_id of the non-target end of the route
  */
@@ -6884,6 +7107,8 @@ LDKChannelInfo ChannelInfo_read(LDKu8slice ser);
 
 void RoutingFees_free(LDKRoutingFees this_ptr);
 
+LDKRoutingFees RoutingFees_clone(const LDKRoutingFees *orig);
+
 /**
  * Flat routing fee in satoshis
  */
index 77b587fd8092788288559f55ee80cb9d87f75cea..49e78e3841eae605119575fd28880e188a2dd327 100644 (file)
@@ -291,6 +291,20 @@ public:
        const LDKChannelMonitor* operator &() const { return &self; }
        const LDKChannelMonitor* operator ->() const { return &self; }
 };
+class Persist {
+private:
+       LDKPersist self;
+public:
+       Persist(const Persist&) = delete;
+       ~Persist() { Persist_free(self); }
+       Persist(Persist&& o) : self(o.self) { memset(&o, 0, sizeof(Persist)); }
+       Persist(LDKPersist&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKPersist)); }
+       operator LDKPersist() { LDKPersist res = self; memset(&self, 0, sizeof(LDKPersist)); return res; }
+       LDKPersist* operator &() { return &self; }
+       LDKPersist* operator ->() { return &self; }
+       const LDKPersist* operator &() const { return &self; }
+       const LDKPersist* operator ->() const { return &self; }
+};
 class OutPoint {
 private:
        LDKOutPoint self;
@@ -1396,6 +1410,20 @@ public:
        const LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* operator &() const { return &self; }
        const LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* operator ->() const { return &self; }
 };
+class C2Tuple_u32TxOutZ {
+private:
+       LDKC2Tuple_u32TxOutZ self;
+public:
+       C2Tuple_u32TxOutZ(const C2Tuple_u32TxOutZ&) = delete;
+       ~C2Tuple_u32TxOutZ() { C2Tuple_u32TxOutZ_free(self); }
+       C2Tuple_u32TxOutZ(C2Tuple_u32TxOutZ&& o) : self(o.self) { memset(&o, 0, sizeof(C2Tuple_u32TxOutZ)); }
+       C2Tuple_u32TxOutZ(LDKC2Tuple_u32TxOutZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKC2Tuple_u32TxOutZ)); }
+       operator LDKC2Tuple_u32TxOutZ() { LDKC2Tuple_u32TxOutZ res = self; memset(&self, 0, sizeof(LDKC2Tuple_u32TxOutZ)); return res; }
+       LDKC2Tuple_u32TxOutZ* operator &() { return &self; }
+       LDKC2Tuple_u32TxOutZ* operator ->() { return &self; }
+       const LDKC2Tuple_u32TxOutZ* operator &() const { return &self; }
+       const LDKC2Tuple_u32TxOutZ* operator ->() const { return &self; }
+};
 class CResult_NoneMonitorUpdateErrorZ {
 private:
        LDKCResult_NoneMonitorUpdateErrorZ self;
@@ -1410,20 +1438,6 @@ public:
        const LDKCResult_NoneMonitorUpdateErrorZ* operator &() const { return &self; }
        const LDKCResult_NoneMonitorUpdateErrorZ* operator ->() const { return &self; }
 };
-class CVec_UpdateFailHTLCZ {
-private:
-       LDKCVec_UpdateFailHTLCZ self;
-public:
-       CVec_UpdateFailHTLCZ(const CVec_UpdateFailHTLCZ&) = delete;
-       ~CVec_UpdateFailHTLCZ() { CVec_UpdateFailHTLCZ_free(self); }
-       CVec_UpdateFailHTLCZ(CVec_UpdateFailHTLCZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_UpdateFailHTLCZ)); }
-       CVec_UpdateFailHTLCZ(LDKCVec_UpdateFailHTLCZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_UpdateFailHTLCZ)); }
-       operator LDKCVec_UpdateFailHTLCZ() { LDKCVec_UpdateFailHTLCZ res = self; memset(&self, 0, sizeof(LDKCVec_UpdateFailHTLCZ)); return res; }
-       LDKCVec_UpdateFailHTLCZ* operator &() { return &self; }
-       LDKCVec_UpdateFailHTLCZ* operator ->() { return &self; }
-       const LDKCVec_UpdateFailHTLCZ* operator &() const { return &self; }
-       const LDKCVec_UpdateFailHTLCZ* operator ->() const { return &self; }
-};
 class CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ {
 private:
        LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ self;
@@ -1438,19 +1452,19 @@ public:
        const LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ* operator &() const { return &self; }
        const LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ* operator ->() const { return &self; }
 };
-class CVec_NodeAnnouncementZ {
+class CVec_PublicKeyZ {
 private:
-       LDKCVec_NodeAnnouncementZ self;
+       LDKCVec_PublicKeyZ self;
 public:
-       CVec_NodeAnnouncementZ(const CVec_NodeAnnouncementZ&) = delete;
-       ~CVec_NodeAnnouncementZ() { CVec_NodeAnnouncementZ_free(self); }
-       CVec_NodeAnnouncementZ(CVec_NodeAnnouncementZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_NodeAnnouncementZ)); }
-       CVec_NodeAnnouncementZ(LDKCVec_NodeAnnouncementZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_NodeAnnouncementZ)); }
-       operator LDKCVec_NodeAnnouncementZ() { LDKCVec_NodeAnnouncementZ res = self; memset(&self, 0, sizeof(LDKCVec_NodeAnnouncementZ)); return res; }
-       LDKCVec_NodeAnnouncementZ* operator &() { return &self; }
-       LDKCVec_NodeAnnouncementZ* operator ->() { return &self; }
-       const LDKCVec_NodeAnnouncementZ* operator &() const { return &self; }
-       const LDKCVec_NodeAnnouncementZ* operator ->() const { return &self; }
+       CVec_PublicKeyZ(const CVec_PublicKeyZ&) = delete;
+       ~CVec_PublicKeyZ() { CVec_PublicKeyZ_free(self); }
+       CVec_PublicKeyZ(CVec_PublicKeyZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_PublicKeyZ)); }
+       CVec_PublicKeyZ(LDKCVec_PublicKeyZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_PublicKeyZ)); }
+       operator LDKCVec_PublicKeyZ() { LDKCVec_PublicKeyZ res = self; memset(&self, 0, sizeof(LDKCVec_PublicKeyZ)); return res; }
+       LDKCVec_PublicKeyZ* operator &() { return &self; }
+       LDKCVec_PublicKeyZ* operator ->() { return &self; }
+       const LDKCVec_PublicKeyZ* operator &() const { return &self; }
+       const LDKCVec_PublicKeyZ* operator ->() const { return &self; }
 };
 class CResult_boolLightningErrorZ {
 private:
@@ -1466,33 +1480,19 @@ public:
        const LDKCResult_boolLightningErrorZ* operator &() const { return &self; }
        const LDKCResult_boolLightningErrorZ* operator ->() const { return &self; }
 };
-class CVec_PublicKeyZ {
+class CVec_C2Tuple_u32TxOutZZ {
 private:
-       LDKCVec_PublicKeyZ self;
+       LDKCVec_C2Tuple_u32TxOutZZ self;
 public:
-       CVec_PublicKeyZ(const CVec_PublicKeyZ&) = delete;
-       ~CVec_PublicKeyZ() { CVec_PublicKeyZ_free(self); }
-       CVec_PublicKeyZ(CVec_PublicKeyZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_PublicKeyZ)); }
-       CVec_PublicKeyZ(LDKCVec_PublicKeyZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_PublicKeyZ)); }
-       operator LDKCVec_PublicKeyZ() { LDKCVec_PublicKeyZ res = self; memset(&self, 0, sizeof(LDKCVec_PublicKeyZ)); return res; }
-       LDKCVec_PublicKeyZ* operator &() { return &self; }
-       LDKCVec_PublicKeyZ* operator ->() { return &self; }
-       const LDKCVec_PublicKeyZ* operator &() const { return &self; }
-       const LDKCVec_PublicKeyZ* operator ->() const { return &self; }
-};
-class CResult_SecretKeySecpErrorZ {
-private:
-       LDKCResult_SecretKeySecpErrorZ self;
-public:
-       CResult_SecretKeySecpErrorZ(const CResult_SecretKeySecpErrorZ&) = delete;
-       ~CResult_SecretKeySecpErrorZ() { CResult_SecretKeySecpErrorZ_free(self); }
-       CResult_SecretKeySecpErrorZ(CResult_SecretKeySecpErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_SecretKeySecpErrorZ)); }
-       CResult_SecretKeySecpErrorZ(LDKCResult_SecretKeySecpErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_SecretKeySecpErrorZ)); }
-       operator LDKCResult_SecretKeySecpErrorZ() { LDKCResult_SecretKeySecpErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_SecretKeySecpErrorZ)); return res; }
-       LDKCResult_SecretKeySecpErrorZ* operator &() { return &self; }
-       LDKCResult_SecretKeySecpErrorZ* operator ->() { return &self; }
-       const LDKCResult_SecretKeySecpErrorZ* operator &() const { return &self; }
-       const LDKCResult_SecretKeySecpErrorZ* operator ->() const { return &self; }
+       CVec_C2Tuple_u32TxOutZZ(const CVec_C2Tuple_u32TxOutZZ&) = delete;
+       ~CVec_C2Tuple_u32TxOutZZ() { CVec_C2Tuple_u32TxOutZZ_free(self); }
+       CVec_C2Tuple_u32TxOutZZ(CVec_C2Tuple_u32TxOutZZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_C2Tuple_u32TxOutZZ)); }
+       CVec_C2Tuple_u32TxOutZZ(LDKCVec_C2Tuple_u32TxOutZZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_C2Tuple_u32TxOutZZ)); }
+       operator LDKCVec_C2Tuple_u32TxOutZZ() { LDKCVec_C2Tuple_u32TxOutZZ res = self; memset(&self, 0, sizeof(LDKCVec_C2Tuple_u32TxOutZZ)); return res; }
+       LDKCVec_C2Tuple_u32TxOutZZ* operator &() { return &self; }
+       LDKCVec_C2Tuple_u32TxOutZZ* operator ->() { return &self; }
+       const LDKCVec_C2Tuple_u32TxOutZZ* operator &() const { return &self; }
+       const LDKCVec_C2Tuple_u32TxOutZZ* operator ->() const { return &self; }
 };
 class CVec_SignatureZ {
 private:
@@ -1550,6 +1550,20 @@ public:
        const LDKCVec_UpdateFailMalformedHTLCZ* operator &() const { return &self; }
        const LDKCVec_UpdateFailMalformedHTLCZ* operator ->() const { return &self; }
 };
+class CResult_SecretKeySecpErrorZ {
+private:
+       LDKCResult_SecretKeySecpErrorZ self;
+public:
+       CResult_SecretKeySecpErrorZ(const CResult_SecretKeySecpErrorZ&) = delete;
+       ~CResult_SecretKeySecpErrorZ() { CResult_SecretKeySecpErrorZ_free(self); }
+       CResult_SecretKeySecpErrorZ(CResult_SecretKeySecpErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_SecretKeySecpErrorZ)); }
+       CResult_SecretKeySecpErrorZ(LDKCResult_SecretKeySecpErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_SecretKeySecpErrorZ)); }
+       operator LDKCResult_SecretKeySecpErrorZ() { LDKCResult_SecretKeySecpErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_SecretKeySecpErrorZ)); return res; }
+       LDKCResult_SecretKeySecpErrorZ* operator &() { return &self; }
+       LDKCResult_SecretKeySecpErrorZ* operator ->() { return &self; }
+       const LDKCResult_SecretKeySecpErrorZ* operator &() const { return &self; }
+       const LDKCResult_SecretKeySecpErrorZ* operator ->() const { return &self; }
+};
 class C2Tuple_HTLCOutputInCommitmentSignatureZ {
 private:
        LDKC2Tuple_HTLCOutputInCommitmentSignatureZ self;
@@ -1858,19 +1872,19 @@ public:
        const LDKCResult_SignatureNoneZ* operator &() const { return &self; }
        const LDKCResult_SignatureNoneZ* operator ->() const { return &self; }
 };
-class C2Tuple_TxidCVec_TxOutZZ {
+class C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ {
 private:
-       LDKC2Tuple_TxidCVec_TxOutZZ self;
+       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ self;
 public:
-       C2Tuple_TxidCVec_TxOutZZ(const C2Tuple_TxidCVec_TxOutZZ&) = delete;
-       ~C2Tuple_TxidCVec_TxOutZZ() { C2Tuple_TxidCVec_TxOutZZ_free(self); }
-       C2Tuple_TxidCVec_TxOutZZ(C2Tuple_TxidCVec_TxOutZZ&& o) : self(o.self) { memset(&o, 0, sizeof(C2Tuple_TxidCVec_TxOutZZ)); }
-       C2Tuple_TxidCVec_TxOutZZ(LDKC2Tuple_TxidCVec_TxOutZZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKC2Tuple_TxidCVec_TxOutZZ)); }
-       operator LDKC2Tuple_TxidCVec_TxOutZZ() { LDKC2Tuple_TxidCVec_TxOutZZ res = self; memset(&self, 0, sizeof(LDKC2Tuple_TxidCVec_TxOutZZ)); return res; }
-       LDKC2Tuple_TxidCVec_TxOutZZ* operator &() { return &self; }
-       LDKC2Tuple_TxidCVec_TxOutZZ* operator ->() { return &self; }
-       const LDKC2Tuple_TxidCVec_TxOutZZ* operator &() const { return &self; }
-       const LDKC2Tuple_TxidCVec_TxOutZZ* operator ->() const { return &self; }
+       C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ(const C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ&) = delete;
+       ~C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ() { C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_free(self); }
+       C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ(C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ&& o) : self(o.self) { memset(&o, 0, sizeof(C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ)); }
+       C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ)); }
+       operator LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ() { LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ res = self; memset(&self, 0, sizeof(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ)); return res; }
+       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ* operator &() { return &self; }
+       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ* operator ->() { return &self; }
+       const LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ* operator &() const { return &self; }
+       const LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ* operator ->() const { return &self; }
 };
 class CVec_ChannelDetailsZ {
 private:
@@ -1900,6 +1914,20 @@ public:
        const LDKCVec_MessageSendEventZ* operator &() const { return &self; }
        const LDKCVec_MessageSendEventZ* operator ->() const { return &self; }
 };
+class CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ {
+private:
+       LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ self;
+public:
+       CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ(const CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ&) = delete;
+       ~CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ() { CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free(self); }
+       CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ(CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ)); }
+       CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ(LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ)); }
+       operator LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ() { LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ res = self; memset(&self, 0, sizeof(LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ)); return res; }
+       LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ* operator &() { return &self; }
+       LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ* operator ->() { return &self; }
+       const LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ* operator &() const { return &self; }
+       const LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ* operator ->() const { return &self; }
+};
 class CResult_NoneAPIErrorZ {
 private:
        LDKCResult_NoneAPIErrorZ self;
@@ -1942,20 +1970,6 @@ public:
        const LDKCVec_NetAddressZ* operator &() const { return &self; }
        const LDKCVec_NetAddressZ* operator ->() const { return &self; }
 };
-class CVec_TxOutZ {
-private:
-       LDKCVec_TxOutZ self;
-public:
-       CVec_TxOutZ(const CVec_TxOutZ&) = delete;
-       ~CVec_TxOutZ() { CVec_TxOutZ_free(self); }
-       CVec_TxOutZ(CVec_TxOutZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_TxOutZ)); }
-       CVec_TxOutZ(LDKCVec_TxOutZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_TxOutZ)); }
-       operator LDKCVec_TxOutZ() { LDKCVec_TxOutZ res = self; memset(&self, 0, sizeof(LDKCVec_TxOutZ)); return res; }
-       LDKCVec_TxOutZ* operator &() { return &self; }
-       LDKCVec_TxOutZ* operator ->() { return &self; }
-       const LDKCVec_TxOutZ* operator &() const { return &self; }
-       const LDKCVec_TxOutZ* operator ->() const { return &self; }
-};
 class C2Tuple_usizeTransactionZ {
 private:
        LDKC2Tuple_usizeTransactionZ self;
@@ -1984,6 +1998,20 @@ public:
        const LDKCVec_C2Tuple_usizeTransactionZZ* operator &() const { return &self; }
        const LDKCVec_C2Tuple_usizeTransactionZZ* operator ->() const { return &self; }
 };
+class CVec_TransactionZ {
+private:
+       LDKCVec_TransactionZ self;
+public:
+       CVec_TransactionZ(const CVec_TransactionZ&) = delete;
+       ~CVec_TransactionZ() { CVec_TransactionZ_free(self); }
+       CVec_TransactionZ(CVec_TransactionZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_TransactionZ)); }
+       CVec_TransactionZ(LDKCVec_TransactionZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_TransactionZ)); }
+       operator LDKCVec_TransactionZ() { LDKCVec_TransactionZ res = self; memset(&self, 0, sizeof(LDKCVec_TransactionZ)); return res; }
+       LDKCVec_TransactionZ* operator &() { return &self; }
+       LDKCVec_TransactionZ* operator ->() { return &self; }
+       const LDKCVec_TransactionZ* operator &() const { return &self; }
+       const LDKCVec_TransactionZ* operator ->() const { return &self; }
+};
 class CVec_ChannelMonitorZ {
 private:
        LDKCVec_ChannelMonitorZ self;
@@ -1998,33 +2026,33 @@ public:
        const LDKCVec_ChannelMonitorZ* operator &() const { return &self; }
        const LDKCVec_ChannelMonitorZ* operator ->() const { return &self; }
 };
-class CVec_TransactionZ {
+class CVec_UpdateFailHTLCZ {
 private:
-       LDKCVec_TransactionZ self;
+       LDKCVec_UpdateFailHTLCZ self;
 public:
-       CVec_TransactionZ(const CVec_TransactionZ&) = delete;
-       ~CVec_TransactionZ() { CVec_TransactionZ_free(self); }
-       CVec_TransactionZ(CVec_TransactionZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_TransactionZ)); }
-       CVec_TransactionZ(LDKCVec_TransactionZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_TransactionZ)); }
-       operator LDKCVec_TransactionZ() { LDKCVec_TransactionZ res = self; memset(&self, 0, sizeof(LDKCVec_TransactionZ)); return res; }
-       LDKCVec_TransactionZ* operator &() { return &self; }
-       LDKCVec_TransactionZ* operator ->() { return &self; }
-       const LDKCVec_TransactionZ* operator &() const { return &self; }
-       const LDKCVec_TransactionZ* operator ->() const { return &self; }
+       CVec_UpdateFailHTLCZ(const CVec_UpdateFailHTLCZ&) = delete;
+       ~CVec_UpdateFailHTLCZ() { CVec_UpdateFailHTLCZ_free(self); }
+       CVec_UpdateFailHTLCZ(CVec_UpdateFailHTLCZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_UpdateFailHTLCZ)); }
+       CVec_UpdateFailHTLCZ(LDKCVec_UpdateFailHTLCZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_UpdateFailHTLCZ)); }
+       operator LDKCVec_UpdateFailHTLCZ() { LDKCVec_UpdateFailHTLCZ res = self; memset(&self, 0, sizeof(LDKCVec_UpdateFailHTLCZ)); return res; }
+       LDKCVec_UpdateFailHTLCZ* operator &() { return &self; }
+       LDKCVec_UpdateFailHTLCZ* operator ->() { return &self; }
+       const LDKCVec_UpdateFailHTLCZ* operator &() const { return &self; }
+       const LDKCVec_UpdateFailHTLCZ* operator ->() const { return &self; }
 };
-class CVec_C2Tuple_TxidCVec_TxOutZZZ {
+class CVec_NodeAnnouncementZ {
 private:
-       LDKCVec_C2Tuple_TxidCVec_TxOutZZZ self;
+       LDKCVec_NodeAnnouncementZ self;
 public:
-       CVec_C2Tuple_TxidCVec_TxOutZZZ(const CVec_C2Tuple_TxidCVec_TxOutZZZ&) = delete;
-       ~CVec_C2Tuple_TxidCVec_TxOutZZZ() { CVec_C2Tuple_TxidCVec_TxOutZZZ_free(self); }
-       CVec_C2Tuple_TxidCVec_TxOutZZZ(CVec_C2Tuple_TxidCVec_TxOutZZZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_C2Tuple_TxidCVec_TxOutZZZ)); }
-       CVec_C2Tuple_TxidCVec_TxOutZZZ(LDKCVec_C2Tuple_TxidCVec_TxOutZZZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_C2Tuple_TxidCVec_TxOutZZZ)); }
-       operator LDKCVec_C2Tuple_TxidCVec_TxOutZZZ() { LDKCVec_C2Tuple_TxidCVec_TxOutZZZ res = self; memset(&self, 0, sizeof(LDKCVec_C2Tuple_TxidCVec_TxOutZZZ)); return res; }
-       LDKCVec_C2Tuple_TxidCVec_TxOutZZZ* operator &() { return &self; }
-       LDKCVec_C2Tuple_TxidCVec_TxOutZZZ* operator ->() { return &self; }
-       const LDKCVec_C2Tuple_TxidCVec_TxOutZZZ* operator &() const { return &self; }
-       const LDKCVec_C2Tuple_TxidCVec_TxOutZZZ* operator ->() const { return &self; }
+       CVec_NodeAnnouncementZ(const CVec_NodeAnnouncementZ&) = delete;
+       ~CVec_NodeAnnouncementZ() { CVec_NodeAnnouncementZ_free(self); }
+       CVec_NodeAnnouncementZ(CVec_NodeAnnouncementZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_NodeAnnouncementZ)); }
+       CVec_NodeAnnouncementZ(LDKCVec_NodeAnnouncementZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_NodeAnnouncementZ)); }
+       operator LDKCVec_NodeAnnouncementZ() { LDKCVec_NodeAnnouncementZ res = self; memset(&self, 0, sizeof(LDKCVec_NodeAnnouncementZ)); return res; }
+       LDKCVec_NodeAnnouncementZ* operator &() { return &self; }
+       LDKCVec_NodeAnnouncementZ* operator ->() { return &self; }
+       const LDKCVec_NodeAnnouncementZ* operator &() const { return &self; }
+       const LDKCVec_NodeAnnouncementZ* operator ->() const { return &self; }
 };
 class C2Tuple_u64u64Z {
 private:
index ca6cdc69fa95cc4fa20ce4223797bfe6025071da..2e15b2a2b2adf1d99d15b7091a40d878f68e8ed1 100644 (file)
@@ -116,6 +116,7 @@ struct nativeCommitmentUpdateOpaque;
 typedef struct nativeCommitmentUpdateOpaque LDKnativeCommitmentUpdate;
 struct nativeMessageHandlerOpaque;
 typedef struct nativeMessageHandlerOpaque LDKnativeMessageHandler;
+typedef struct LDKSocketDescriptor LDKSocketDescriptor;
 struct nativePeerHandleErrorOpaque;
 typedef struct nativePeerHandleErrorOpaque LDKnativePeerHandleError;
 struct nativePeerManagerOpaque;
index d084a1562274f26f865d1ce0a499fb97631631ee..fd77e0d4cf11cbcba6777980a73e64ea97849f67 100644 (file)
@@ -73,23 +73,32 @@ pub type CVec_TransactionZ = crate::c_types::CVecTempl<crate::c_types::Transacti
 pub static CVec_TransactionZ_free: extern "C" fn(CVec_TransactionZ) = crate::c_types::CVecTempl_free::<crate::c_types::Transaction>;
 
 #[no_mangle]
-pub type CVec_TxOutZ = crate::c_types::CVecTempl<crate::c_types::TxOut>;
+pub type C2Tuple_u32TxOutZ = crate::c_types::C2TupleTempl<u32, crate::c_types::TxOut>;
 #[no_mangle]
-pub static CVec_TxOutZ_free: extern "C" fn(CVec_TxOutZ) = crate::c_types::CVecTempl_free::<crate::c_types::TxOut>;
+pub static C2Tuple_u32TxOutZ_free: extern "C" fn(C2Tuple_u32TxOutZ) = crate::c_types::C2TupleTempl_free::<u32, crate::c_types::TxOut>;
+#[no_mangle]
+pub extern "C" fn C2Tuple_u32TxOutZ_new(a: u32, b: crate::c_types::TxOut) -> C2Tuple_u32TxOutZ {
+       C2Tuple_u32TxOutZ { a, b, }
+}
+
+#[no_mangle]
+pub type CVec_C2Tuple_u32TxOutZZ = crate::c_types::CVecTempl<crate::c_types::C2TupleTempl<u32, crate::c_types::TxOut>>;
+#[no_mangle]
+pub static CVec_C2Tuple_u32TxOutZZ_free: extern "C" fn(CVec_C2Tuple_u32TxOutZZ) = crate::c_types::CVecTempl_free::<crate::c_types::C2TupleTempl<u32, crate::c_types::TxOut>>;
 
 #[no_mangle]
-pub type C2Tuple_TxidCVec_TxOutZZ = crate::c_types::C2TupleTempl<crate::c_types::ThirtyTwoBytes, crate::c_types::CVecTempl<crate::c_types::TxOut>>;
+pub type C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ = crate::c_types::C2TupleTempl<crate::c_types::ThirtyTwoBytes, crate::c_types::CVecTempl<crate::c_types::C2TupleTempl<u32, crate::c_types::TxOut>>>;
 #[no_mangle]
-pub static C2Tuple_TxidCVec_TxOutZZ_free: extern "C" fn(C2Tuple_TxidCVec_TxOutZZ) = crate::c_types::C2TupleTempl_free::<crate::c_types::ThirtyTwoBytes, crate::c_types::CVecTempl<crate::c_types::TxOut>>;
+pub static C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_free: extern "C" fn(C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ) = crate::c_types::C2TupleTempl_free::<crate::c_types::ThirtyTwoBytes, crate::c_types::CVecTempl<crate::c_types::C2TupleTempl<u32, crate::c_types::TxOut>>>;
 #[no_mangle]
-pub extern "C" fn C2Tuple_TxidCVec_TxOutZZ_new(a: crate::c_types::ThirtyTwoBytes, b: crate::c_types::derived::CVec_TxOutZ) -> C2Tuple_TxidCVec_TxOutZZ {
-       C2Tuple_TxidCVec_TxOutZZ { a, b, }
+pub extern "C" fn C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_new(a: crate::c_types::ThirtyTwoBytes, b: crate::c_types::derived::CVec_C2Tuple_u32TxOutZZ) -> C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ {
+       C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ { a, b, }
 }
 
 #[no_mangle]
-pub type CVec_C2Tuple_TxidCVec_TxOutZZZ = crate::c_types::CVecTempl<crate::c_types::C2TupleTempl<crate::c_types::ThirtyTwoBytes, crate::c_types::CVecTempl<crate::c_types::TxOut>>>;
+pub type CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ = crate::c_types::CVecTempl<crate::c_types::C2TupleTempl<crate::c_types::ThirtyTwoBytes, crate::c_types::CVecTempl<crate::c_types::C2TupleTempl<u32, crate::c_types::TxOut>>>>;
 #[no_mangle]
-pub static CVec_C2Tuple_TxidCVec_TxOutZZZ_free: extern "C" fn(CVec_C2Tuple_TxidCVec_TxOutZZZ) = crate::c_types::CVecTempl_free::<crate::c_types::C2TupleTempl<crate::c_types::ThirtyTwoBytes, crate::c_types::CVecTempl<crate::c_types::TxOut>>>;
+pub static CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free: extern "C" fn(CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ) = crate::c_types::CVecTempl_free::<crate::c_types::C2TupleTempl<crate::c_types::ThirtyTwoBytes, crate::c_types::CVecTempl<crate::c_types::C2TupleTempl<u32, crate::c_types::TxOut>>>>;
 
 #[no_mangle]
 pub type C2Tuple_u64u64Z = crate::c_types::C2TupleTempl<u64, u64>;
index d14fe6fc792df937f914aae656e8b61dfd52e773..1919277902306bfcf98b36b0661189b0538ec921 100644 (file)
@@ -100,7 +100,8 @@ impl Secp256k1Error {
 /// set. Similarly, while it may change in the future, all `Transaction`s you pass to Rust may have
 /// `data_is_owned` either set or unset at your discretion.
 pub struct Transaction {
-       pub data: *const u8,
+       /// This is non-const for your convenience, an object passed to Rust is never written to.
+       pub data: *mut u8,
        pub datalen: usize,
        pub data_is_owned: bool,
 }
@@ -319,7 +320,7 @@ impl<T: Clone> Clone for CVecTempl<T> {
        fn clone(&self) -> Self {
                let mut res = Vec::new();
                if self.datalen == 0 { return Self::from(res); }
-               res.clone_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
+               res.extend_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
                Self::from(res)
        }
 }
index ef524b568de24cbdaf1d2c880171bd1c8be71c81..b5f51032326edc1cac5ae8b0e763c4d4e9b82082 100644 (file)
@@ -93,6 +93,10 @@ impl ConfirmationTarget {
                }
        }
 }
+#[no_mangle]
+pub extern "C" fn ConfirmationTarget_clone(orig: &ConfirmationTarget) -> ConfirmationTarget {
+       orig.clone()
+}
 /// A trait which should be implemented to provide feerate information on a number of time
 /// horizons.
 ///
index 539b8450eb9141f3025750b2ef6ec197ad6ce0c4..35eb1bed22d1e442c7bfbbc9991156e0cd72cc84 100644 (file)
@@ -26,7 +26,7 @@ use crate::c_types::*;
 
 
 use lightning::chain::chainmonitor::ChainMonitor as nativeChainMonitorImport;
-type nativeChainMonitor = nativeChainMonitorImport<crate::chain::keysinterface::ChannelKeys, crate::chain::Filter, crate::chain::chaininterface::BroadcasterInterface, crate::chain::chaininterface::FeeEstimator, crate::util::logger::Logger>;
+type nativeChainMonitor = nativeChainMonitorImport<crate::chain::keysinterface::ChannelKeys, crate::chain::Filter, crate::chain::chaininterface::BroadcasterInterface, crate::chain::chaininterface::FeeEstimator, crate::util::logger::Logger, crate::chain::channelmonitor::Persist>;
 
 /// An implementation of [`chain::Watch`] for monitoring channels.
 ///
@@ -111,9 +111,9 @@ pub extern "C" fn ChainMonitor_block_disconnected(this_arg: &ChainMonitor, heade
 /// [`chain::Filter`]: ../trait.Filter.html
 #[must_use]
 #[no_mangle]
-pub extern "C" fn ChainMonitor_new(chain_source: *mut crate::chain::Filter, mut broadcaster: crate::chain::chaininterface::BroadcasterInterface, mut logger: crate::util::logger::Logger, mut feeest: crate::chain::chaininterface::FeeEstimator) -> ChainMonitor {
+pub extern "C" fn ChainMonitor_new(chain_source: *mut crate::chain::Filter, mut broadcaster: crate::chain::chaininterface::BroadcasterInterface, mut logger: crate::util::logger::Logger, mut feeest: crate::chain::chaininterface::FeeEstimator, mut persister: crate::chain::channelmonitor::Persist) -> ChainMonitor {
        let mut local_chain_source = if chain_source == std::ptr::null_mut() { None } else { Some( { unsafe { *Box::from_raw(chain_source) } }) };
-       let mut ret = lightning::chain::chainmonitor::ChainMonitor::new(local_chain_source, broadcaster, logger, feeest);
+       let mut ret = lightning::chain::chainmonitor::ChainMonitor::new(local_chain_source, broadcaster, logger, feeest, persister);
        ChainMonitor { inner: Box::into_raw(Box::new(ret)), is_owned: true }
 }
 
@@ -129,8 +129,8 @@ pub extern "C" fn ChainMonitor_as_Watch(this_arg: *const ChainMonitor) -> crate:
 }
 use lightning::chain::Watch as WatchTraitImport;
 #[must_use]
-extern "C" fn ChainMonitor_Watch_watch_channel(this_arg: *const c_void, mut funding_txo: crate::chain::transaction::OutPoint, mut monitor: crate::chain::channelmonitor::ChannelMonitor) -> crate::c_types::derived::CResult_NoneChannelMonitorUpdateErrZ {
-       let mut ret = unsafe { &mut *(this_arg as *mut nativeChainMonitor) }.watch_channel(*unsafe { Box::from_raw(funding_txo.take_ptr()) }, *unsafe { Box::from_raw(monitor.take_ptr()) });
+extern "C" fn ChainMonitor_Watch_watch_channel(this_arg: *const c_void, mut funding_outpoint: crate::chain::transaction::OutPoint, mut monitor: crate::chain::channelmonitor::ChannelMonitor) -> crate::c_types::derived::CResult_NoneChannelMonitorUpdateErrZ {
+       let mut ret = unsafe { &mut *(this_arg as *mut nativeChainMonitor) }.watch_channel(*unsafe { Box::from_raw(funding_outpoint.take_ptr()) }, *unsafe { Box::from_raw(monitor.take_ptr()) });
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::chain::channelmonitor::ChannelMonitorUpdateErr::native_into(e) }) };
        local_ret
 }
index 79c84d53ea0eb2b3a2a2a42cebce2bb8ab1db905..c644670257b2b34bcded75a22f1f3bdc02693ed8 100644 (file)
@@ -69,13 +69,23 @@ impl Clone for ChannelMonitorUpdate {
 pub(crate) extern "C" fn ChannelMonitorUpdate_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelMonitorUpdate)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ChannelMonitorUpdate_clone(orig: &ChannelMonitorUpdate) -> ChannelMonitorUpdate {
+       ChannelMonitorUpdate { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The sequence number of this update. Updates *must* be replayed in-order according to this
 /// sequence number (and updates may panic if they are not). The update_id values are strictly
-/// increasing and increase by one for each new update.
+/// increasing and increase by one for each new update, with one exception specified below.
 ///
 /// This sequence number is also used to track up to which points updates which returned
 /// ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
 /// ChannelMonitor when ChannelManager::channel_monitor_updated is called.
+///
+/// The only instance where update_id values are not strictly increasing is the case where we
+/// allow post-force-close updates with a special update ID of [`CLOSED_CHANNEL_UPDATE_ID`]. See
+/// its docs for more details.
+///
+/// [`CLOSED_CHANNEL_UPDATE_ID`]: constant.CLOSED_CHANNEL_UPDATE_ID.html
 #[no_mangle]
 pub extern "C" fn ChannelMonitorUpdate_get_update_id(this_ptr: &ChannelMonitorUpdate) -> u64 {
        let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.update_id;
@@ -83,15 +93,24 @@ pub extern "C" fn ChannelMonitorUpdate_get_update_id(this_ptr: &ChannelMonitorUp
 }
 /// The sequence number of this update. Updates *must* be replayed in-order according to this
 /// sequence number (and updates may panic if they are not). The update_id values are strictly
-/// increasing and increase by one for each new update.
+/// increasing and increase by one for each new update, with one exception specified below.
 ///
 /// This sequence number is also used to track up to which points updates which returned
 /// ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
 /// ChannelMonitor when ChannelManager::channel_monitor_updated is called.
+///
+/// The only instance where update_id values are not strictly increasing is the case where we
+/// allow post-force-close updates with a special update ID of [`CLOSED_CHANNEL_UPDATE_ID`]. See
+/// its docs for more details.
+///
+/// [`CLOSED_CHANNEL_UPDATE_ID`]: constant.CLOSED_CHANNEL_UPDATE_ID.html
 #[no_mangle]
 pub extern "C" fn ChannelMonitorUpdate_set_update_id(this_ptr: &mut ChannelMonitorUpdate, mut val: u64) {
        unsafe { &mut *this_ptr.inner }.update_id = val;
 }
+
+#[no_mangle]
+pub static CLOSED_CHANNEL_UPDATE_ID: u64 = lightning::chain::channelmonitor::CLOSED_CHANNEL_UPDATE_ID;
 #[no_mangle]
 pub extern "C" fn ChannelMonitorUpdate_write(obj: *const ChannelMonitorUpdate) -> crate::c_types::derived::CVec_u8Z {
        crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
@@ -197,6 +216,10 @@ impl ChannelMonitorUpdateErr {
                }
        }
 }
+#[no_mangle]
+pub extern "C" fn ChannelMonitorUpdateErr_clone(orig: &ChannelMonitorUpdateErr) -> ChannelMonitorUpdateErr {
+       orig.clone()
+}
 
 use lightning::chain::channelmonitor::MonitorUpdateError as nativeMonitorUpdateErrorImport;
 type nativeMonitorUpdateError = nativeMonitorUpdateErrorImport;
@@ -205,7 +228,7 @@ type nativeMonitorUpdateError = nativeMonitorUpdateErrorImport;
 /// inconsistent with the ChannelMonitor being called. eg for ChannelMonitor::update_monitor this
 /// means you tried to update a monitor for a different channel or the ChannelMonitorUpdate was
 /// corrupted.
-/// Contains a human-readable error message.
+/// Contains a developer-readable error message.
 #[must_use]
 #[repr(C)]
 pub struct MonitorUpdateError {
@@ -277,6 +300,23 @@ impl MonitorEvent {
                ret
        }
 }
+impl Clone for MonitorEvent {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
+                       is_owned: true,
+               }
+       }
+}
+#[allow(unused)]
+/// Used only if an object of this type is returned as a trait impl by a method
+pub(crate) extern "C" fn MonitorEvent_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeMonitorEvent)).clone() })) as *mut c_void
+}
+#[no_mangle]
+pub extern "C" fn MonitorEvent_clone(orig: &MonitorEvent) -> MonitorEvent {
+       MonitorEvent { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 
 use lightning::chain::channelmonitor::HTLCUpdate as nativeHTLCUpdateImport;
 type nativeHTLCUpdate = nativeHTLCUpdateImport;
@@ -333,6 +373,10 @@ pub(crate) extern "C" fn HTLCUpdate_clone_void(this_ptr: *const c_void) -> *mut
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeHTLCUpdate)).clone() })) as *mut c_void
 }
 #[no_mangle]
+pub extern "C" fn HTLCUpdate_clone(orig: &HTLCUpdate) -> HTLCUpdate {
+       HTLCUpdate { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
+#[no_mangle]
 pub extern "C" fn HTLCUpdate_write(obj: *const HTLCUpdate) -> crate::c_types::derived::CVec_u8Z {
        crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
 }
@@ -397,8 +441,8 @@ impl ChannelMonitor {
 /// panics if the given update is not the next update by update_id.
 #[must_use]
 #[no_mangle]
-pub extern "C" fn ChannelMonitor_update_monitor(this_arg: &mut ChannelMonitor, mut updates: crate::chain::channelmonitor::ChannelMonitorUpdate, broadcaster: &crate::chain::chaininterface::BroadcasterInterface, logger: &crate::util::logger::Logger) -> crate::c_types::derived::CResult_NoneMonitorUpdateErrorZ {
-       let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.update_monitor(*unsafe { Box::from_raw(updates.take_ptr()) }, broadcaster, logger);
+pub extern "C" fn ChannelMonitor_update_monitor(this_arg: &mut ChannelMonitor, updates: &crate::chain::channelmonitor::ChannelMonitorUpdate, broadcaster: &crate::chain::chaininterface::BroadcasterInterface, fee_estimator: &crate::chain::chaininterface::FeeEstimator, logger: &crate::util::logger::Logger) -> crate::c_types::derived::CResult_NoneMonitorUpdateErrorZ {
+       let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.update_monitor(unsafe { &*updates.inner }, broadcaster, fee_estimator, logger);
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::chain::channelmonitor::MonitorUpdateError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
        local_ret
 }
@@ -477,10 +521,10 @@ pub extern "C" fn ChannelMonitor_get_latest_holder_commitment_txn(this_arg: &mut
 /// [`get_outputs_to_watch`]: #method.get_outputs_to_watch
 #[must_use]
 #[no_mangle]
-pub extern "C" fn ChannelMonitor_block_connected(this_arg: &mut ChannelMonitor, header: *const [u8; 80], mut txdata: crate::c_types::derived::CVec_C2Tuple_usizeTransactionZZ, mut height: u32, mut broadcaster: crate::chain::chaininterface::BroadcasterInterface, mut fee_estimator: crate::chain::chaininterface::FeeEstimator, mut logger: crate::util::logger::Logger) -> crate::c_types::derived::CVec_C2Tuple_TxidCVec_TxOutZZZ {
+pub extern "C" fn ChannelMonitor_block_connected(this_arg: &mut ChannelMonitor, header: *const [u8; 80], mut txdata: crate::c_types::derived::CVec_C2Tuple_usizeTransactionZZ, mut height: u32, mut broadcaster: crate::chain::chaininterface::BroadcasterInterface, mut fee_estimator: crate::chain::chaininterface::FeeEstimator, mut logger: crate::util::logger::Logger) -> crate::c_types::derived::CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ {
        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 }); };
        let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.block_connected(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), &local_txdata.iter().map(|(a, b)| (*a, b)).collect::<Vec<_>>()[..], height, broadcaster, fee_estimator, logger);
-       let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { let (mut orig_ret_0_0, mut orig_ret_0_1) = item; let mut local_orig_ret_0_1 = Vec::new(); for item in orig_ret_0_1.drain(..) { local_orig_ret_0_1.push( { crate::c_types::TxOut::from_rust(item) }); }; let mut local_ret_0 = (crate::c_types::ThirtyTwoBytes { data: orig_ret_0_0.into_inner() }, local_orig_ret_0_1.into()).into(); local_ret_0 }); };
+       let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { let (mut orig_ret_0_0, mut orig_ret_0_1) = item; let mut local_orig_ret_0_1 = Vec::new(); for item in orig_ret_0_1.drain(..) { local_orig_ret_0_1.push( { let (mut orig_orig_ret_0_1_0_0, mut orig_orig_ret_0_1_0_1) = item; let mut local_orig_ret_0_1_0 = (orig_orig_ret_0_1_0_0, crate::c_types::TxOut::from_rust(orig_orig_ret_0_1_0_1)).into(); local_orig_ret_0_1_0 }); }; let mut local_ret_0 = (crate::c_types::ThirtyTwoBytes { data: orig_ret_0_0.into_inner() }, local_orig_ret_0_1.into()).into(); local_ret_0 }); };
        local_ret.into()
 }
 
@@ -491,3 +535,96 @@ pub extern "C" fn ChannelMonitor_block_disconnected(this_arg: &mut ChannelMonito
        unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.block_disconnected(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), height, broadcaster, fee_estimator, logger)
 }
 
+/// `Persist` defines behavior for persisting channel monitors: this could mean
+/// writing once to disk, and/or uploading to one or more backup services.
+///
+/// Note that for every new monitor, you **must** persist the new `ChannelMonitor`
+/// to disk/backups. And, on every update, you **must** persist either the
+/// `ChannelMonitorUpdate` or the updated monitor itself. Otherwise, there is risk
+/// of situations such as revoking a transaction, then crashing before this
+/// revocation can be persisted, then unintentionally broadcasting a revoked
+/// transaction and losing money. This is a risk because previous channel states
+/// are toxic, so it's important that whatever channel state is persisted is
+/// kept up-to-date.
+#[repr(C)]
+pub struct Persist {
+       pub this_arg: *mut c_void,
+       /// Persist a new channel's data. The data can be stored any way you want, but
+       /// the identifier provided by Rust-Lightning is the channel's outpoint (and
+       /// it is up to you to maintain a correct mapping between the outpoint and the
+       /// stored channel data). Note that you **must** persist every new monitor to
+       /// disk. See the `Persist` trait documentation for more details.
+       ///
+       /// See [`ChannelMonitor::serialize_for_disk`] for writing out a `ChannelMonitor`,
+       /// and [`ChannelMonitorUpdateErr`] for requirements when returning errors.
+       ///
+       /// [`ChannelMonitor::serialize_for_disk`]: struct.ChannelMonitor.html#method.serialize_for_disk
+       /// [`ChannelMonitorUpdateErr`]: enum.ChannelMonitorUpdateErr.html
+       #[must_use]
+       pub persist_new_channel: extern "C" fn (this_arg: *const c_void, id: crate::chain::transaction::OutPoint, data: &crate::chain::channelmonitor::ChannelMonitor) -> crate::c_types::derived::CResult_NoneChannelMonitorUpdateErrZ,
+       /// Update one channel's data. The provided `ChannelMonitor` has already
+       /// applied the given update.
+       ///
+       /// Note that on every update, you **must** persist either the
+       /// `ChannelMonitorUpdate` or the updated monitor itself to disk/backups. See
+       /// the `Persist` trait documentation for more details.
+       ///
+       /// If an implementer chooses to persist the updates only, they need to make
+       /// sure that all the updates are applied to the `ChannelMonitors` *before*
+       /// the set of channel monitors is given to the `ChannelManager`
+       /// deserialization routine. See [`ChannelMonitor::update_monitor`] for
+       /// applying a monitor update to a monitor. If full `ChannelMonitors` are
+       /// persisted, then there is no need to persist individual updates.
+       ///
+       /// Note that there could be a performance tradeoff between persisting complete
+       /// channel monitors on every update vs. persisting only updates and applying
+       /// them in batches. The size of each monitor grows `O(number of state updates)`
+       /// whereas updates are small and `O(1)`.
+       ///
+       /// See [`ChannelMonitor::serialize_for_disk`] for writing out a `ChannelMonitor`,
+       /// [`ChannelMonitorUpdate::write`] for writing out an update, and
+       /// [`ChannelMonitorUpdateErr`] for requirements when returning errors.
+       ///
+       /// [`ChannelMonitor::update_monitor`]: struct.ChannelMonitor.html#impl-1
+       /// [`ChannelMonitor::serialize_for_disk`]: struct.ChannelMonitor.html#method.serialize_for_disk
+       /// [`ChannelMonitorUpdate::write`]: struct.ChannelMonitorUpdate.html#method.write
+       /// [`ChannelMonitorUpdateErr`]: enum.ChannelMonitorUpdateErr.html
+       #[must_use]
+       pub update_persisted_channel: extern "C" fn (this_arg: *const c_void, id: crate::chain::transaction::OutPoint, update: &crate::chain::channelmonitor::ChannelMonitorUpdate, data: &crate::chain::channelmonitor::ChannelMonitor) -> crate::c_types::derived::CResult_NoneChannelMonitorUpdateErrZ,
+       pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
+}
+unsafe impl Send for Persist {}
+unsafe impl Sync for Persist {}
+
+use lightning::chain::channelmonitor::Persist as rustPersist;
+impl rustPersist<crate::chain::keysinterface::ChannelKeys> for Persist {
+       fn persist_new_channel(&self, id: lightning::chain::transaction::OutPoint, data: &lightning::chain::channelmonitor::ChannelMonitor<crate::chain::keysinterface::ChannelKeys>) -> Result<(), lightning::chain::channelmonitor::ChannelMonitorUpdateErr> {
+               let mut ret = (self.persist_new_channel)(self.this_arg, crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(id)), is_owned: true }, &crate::chain::channelmonitor::ChannelMonitor { inner: unsafe { (data as *const _) as *mut _ }, is_owned: false });
+               let mut local_ret = match ret.result_ok { true => Ok( { () /*(*unsafe { Box::from_raw(ret.contents.result.take_ptr()) })*/ }), false => Err( { (*unsafe { Box::from_raw(ret.contents.err.take_ptr()) }).into_native() })};
+               local_ret
+       }
+       fn update_persisted_channel(&self, id: lightning::chain::transaction::OutPoint, update: &lightning::chain::channelmonitor::ChannelMonitorUpdate, data: &lightning::chain::channelmonitor::ChannelMonitor<crate::chain::keysinterface::ChannelKeys>) -> Result<(), lightning::chain::channelmonitor::ChannelMonitorUpdateErr> {
+               let mut ret = (self.update_persisted_channel)(self.this_arg, crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(id)), is_owned: true }, &crate::chain::channelmonitor::ChannelMonitorUpdate { inner: unsafe { (update as *const _) as *mut _ }, is_owned: false }, &crate::chain::channelmonitor::ChannelMonitor { inner: unsafe { (data as *const _) as *mut _ }, is_owned: false });
+               let mut local_ret = match ret.result_ok { true => Ok( { () /*(*unsafe { Box::from_raw(ret.contents.result.take_ptr()) })*/ }), false => Err( { (*unsafe { Box::from_raw(ret.contents.err.take_ptr()) }).into_native() })};
+               local_ret
+       }
+}
+
+// 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 Persist {
+       type Target = Self;
+       fn deref(&self) -> &Self {
+               self
+       }
+}
+/// Calls the free function if one is set
+#[no_mangle]
+pub extern "C" fn Persist_free(this_ptr: Persist) { }
+impl Drop for Persist {
+       fn drop(&mut self) {
+               if let Some(f) = self.free {
+                       f(self.this_arg);
+               }
+       }
+}
index 8d8a0acd129f29fd383c9fad62531a4053edc4bb..afa982bc45cfdabe65855595a130ee57856e36a5 100644 (file)
@@ -220,6 +220,10 @@ impl SpendableOutputDescriptor {
 }
 #[no_mangle]
 pub extern "C" fn SpendableOutputDescriptor_free(this_ptr: SpendableOutputDescriptor) { }
+#[no_mangle]
+pub extern "C" fn SpendableOutputDescriptor_clone(orig: &SpendableOutputDescriptor) -> SpendableOutputDescriptor {
+       orig.clone()
+}
 /// Set of lightning keys needed to operate a channel as described in BOLT 3.
 ///
 /// Signing services could be implemented on a hardware wallet. In this case,
@@ -362,26 +366,30 @@ pub struct ChannelKeys {
        pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
 }
 unsafe impl Send for ChannelKeys {}
+#[no_mangle]
+pub extern "C" fn ChannelKeys_clone(orig: &ChannelKeys) -> ChannelKeys {
+       ChannelKeys {
+               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(),
+               key_derivation_params: orig.key_derivation_params.clone(),
+               sign_counterparty_commitment: orig.sign_counterparty_commitment.clone(),
+               sign_holder_commitment: orig.sign_holder_commitment.clone(),
+               sign_holder_commitment_htlc_transactions: orig.sign_holder_commitment_htlc_transactions.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(),
+               on_accept: orig.on_accept.clone(),
+               clone: orig.clone.clone(),
+               free: orig.free.clone(),
+       }
+}
 impl Clone for ChannelKeys {
        fn clone(&self) -> Self {
-               Self {
-               this_arg: if let Some(f) = self.clone { (f)(self.this_arg) } else { self.this_arg },
-                       get_per_commitment_point: self.get_per_commitment_point.clone(),
-                       release_commitment_secret: self.release_commitment_secret.clone(),
-                       pubkeys: self.pubkeys.clone(),
-                       set_pubkeys: self.set_pubkeys.clone(),
-                       key_derivation_params: self.key_derivation_params.clone(),
-                       sign_counterparty_commitment: self.sign_counterparty_commitment.clone(),
-                       sign_holder_commitment: self.sign_holder_commitment.clone(),
-                       sign_holder_commitment_htlc_transactions: self.sign_holder_commitment_htlc_transactions.clone(),
-                       sign_justice_transaction: self.sign_justice_transaction.clone(),
-                       sign_counterparty_htlc_transaction: self.sign_counterparty_htlc_transaction.clone(),
-                       sign_closing_transaction: self.sign_closing_transaction.clone(),
-                       sign_channel_announcement: self.sign_channel_announcement.clone(),
-                       on_accept: self.on_accept.clone(),
-                       clone: self.clone.clone(),
-                       free: self.free.clone(),
-               }
+               ChannelKeys_clone(self)
        }
 }
 
@@ -591,6 +599,10 @@ impl Clone for InMemoryChannelKeys {
 pub(crate) extern "C" fn InMemoryChannelKeys_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeInMemoryChannelKeys)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn InMemoryChannelKeys_clone(orig: &InMemoryChannelKeys) -> InMemoryChannelKeys {
+       InMemoryChannelKeys { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Private key of anchor tx
 #[no_mangle]
 pub extern "C" fn InMemoryChannelKeys_get_funding_key(this_ptr: &InMemoryChannelKeys) -> *const [u8; 32] {
index cbfa6074ada4f2f3055c733784c0a0a5e3552570..6ea4d99db9df9e403b29f8aa8f4a52ede7df17d4 100644 (file)
@@ -52,6 +52,10 @@ impl AccessError {
                }
        }
 }
+#[no_mangle]
+pub extern "C" fn AccessError_clone(orig: &AccessError) -> AccessError {
+       orig.clone()
+}
 /// The `Access` trait defines behavior for accessing chain data and state, such as blocks and
 /// UTXOs.
 #[repr(C)]
index 9d099cb6939f52a664e2d66fce645a1841ce5977..3a35c4727f937183018e304786e6cf4029c2fda4 100644 (file)
@@ -58,6 +58,10 @@ impl Clone for OutPoint {
 pub(crate) extern "C" fn OutPoint_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeOutPoint)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn OutPoint_clone(orig: &OutPoint) -> OutPoint {
+       OutPoint { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The referenced transaction's txid.
 #[no_mangle]
 pub extern "C" fn OutPoint_get_txid(this_ptr: &OutPoint) -> *const [u8; 32] {
index 038ad71c051d27f53e36f683ea4bcf3d70c0e2f3..f9e6c407ef036df18c28e437c1d18ea2bec19543 100644 (file)
@@ -133,6 +133,10 @@ impl Clone for TxCreationKeys {
 pub(crate) extern "C" fn TxCreationKeys_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeTxCreationKeys)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn TxCreationKeys_clone(orig: &TxCreationKeys) -> TxCreationKeys {
+       TxCreationKeys { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The broadcaster's per-commitment public key which was used to derive the other keys.
 #[no_mangle]
 pub extern "C" fn TxCreationKeys_get_per_commitment_point(this_ptr: &TxCreationKeys) -> crate::c_types::PublicKey {
@@ -256,6 +260,23 @@ impl PreCalculatedTxCreationKeys {
                ret
        }
 }
+impl Clone for PreCalculatedTxCreationKeys {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
+                       is_owned: true,
+               }
+       }
+}
+#[allow(unused)]
+/// Used only if an object of this type is returned as a trait impl by a method
+pub(crate) extern "C" fn PreCalculatedTxCreationKeys_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativePreCalculatedTxCreationKeys)).clone() })) as *mut c_void
+}
+#[no_mangle]
+pub extern "C" fn PreCalculatedTxCreationKeys_clone(orig: &PreCalculatedTxCreationKeys) -> PreCalculatedTxCreationKeys {
+       PreCalculatedTxCreationKeys { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
 #[must_use]
 #[no_mangle]
@@ -332,6 +353,10 @@ impl Clone for ChannelPublicKeys {
 pub(crate) extern "C" fn ChannelPublicKeys_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelPublicKeys)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ChannelPublicKeys_clone(orig: &ChannelPublicKeys) -> ChannelPublicKeys {
+       ChannelPublicKeys { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The public key which is used to sign all commitment transactions, as it appears in the
 /// on-chain channel lock-in 2-of-2 multisig output.
 #[no_mangle]
@@ -497,6 +522,10 @@ impl Clone for HTLCOutputInCommitment {
 pub(crate) extern "C" fn HTLCOutputInCommitment_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeHTLCOutputInCommitment)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn HTLCOutputInCommitment_clone(orig: &HTLCOutputInCommitment) -> HTLCOutputInCommitment {
+       HTLCOutputInCommitment { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Whether the HTLC was \"offered\" (ie outbound in relation to this commitment transaction).
 /// Note that this is not the same as whether it is ountbound *from us*. To determine that you
 /// need to compare this value to whether the commitment transaction in question is that of
@@ -638,6 +667,10 @@ impl Clone for HolderCommitmentTransaction {
 pub(crate) extern "C" fn HolderCommitmentTransaction_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeHolderCommitmentTransaction)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn HolderCommitmentTransaction_clone(orig: &HolderCommitmentTransaction) -> HolderCommitmentTransaction {
+       HolderCommitmentTransaction { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The commitment transaction itself, in unsigned form.
 #[no_mangle]
 pub extern "C" fn HolderCommitmentTransaction_get_unsigned_tx(this_ptr: &HolderCommitmentTransaction) -> crate::c_types::Transaction {
index 7d9028a572586b66fbb62d2535d44d3ae9dc7f88..c21f26e94e05bfc2c7c3bb4069f4135293e10f5f 100644 (file)
@@ -124,6 +124,23 @@ impl ChannelDetails {
                ret
        }
 }
+impl Clone for ChannelDetails {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
+                       is_owned: true,
+               }
+       }
+}
+#[allow(unused)]
+/// Used only if an object of this type is returned as a trait impl by a method
+pub(crate) extern "C" fn ChannelDetails_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelDetails)).clone() })) as *mut c_void
+}
+#[no_mangle]
+pub extern "C" fn ChannelDetails_clone(orig: &ChannelDetails) -> ChannelDetails {
+       ChannelDetails { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
 /// thereafter this is the txid of the funding transaction xor the funding transaction output).
 /// Note that this means this value is *not* persistent - it can change once during the
index 6925139d69392335e62ca8176160cecc0f0a5995..401da37772c30c8afca85ccdf96b86ae0d19f8b0 100644 (file)
@@ -95,6 +95,23 @@ impl Init {
                ret
        }
 }
+impl Clone for Init {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
+                       is_owned: true,
+               }
+       }
+}
+#[allow(unused)]
+/// Used only if an object of this type is returned as a trait impl by a method
+pub(crate) extern "C" fn Init_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeInit)).clone() })) as *mut c_void
+}
+#[no_mangle]
+pub extern "C" fn Init_clone(orig: &Init) -> Init {
+       Init { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 
 use lightning::ln::msgs::ErrorMessage as nativeErrorMessageImport;
 type nativeErrorMessage = nativeErrorMessageImport;
@@ -146,6 +163,10 @@ impl Clone for ErrorMessage {
 pub(crate) extern "C" fn ErrorMessage_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeErrorMessage)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ErrorMessage_clone(orig: &ErrorMessage) -> ErrorMessage {
+       ErrorMessage { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID involved in the error
 #[no_mangle]
 pub extern "C" fn ErrorMessage_get_channel_id(this_ptr: &ErrorMessage) -> *const [u8; 32] {
@@ -220,6 +241,23 @@ impl Ping {
                ret
        }
 }
+impl Clone for Ping {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
+                       is_owned: true,
+               }
+       }
+}
+#[allow(unused)]
+/// Used only if an object of this type is returned as a trait impl by a method
+pub(crate) extern "C" fn Ping_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativePing)).clone() })) as *mut c_void
+}
+#[no_mangle]
+pub extern "C" fn Ping_clone(orig: &Ping) -> Ping {
+       Ping { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The desired response length
 #[no_mangle]
 pub extern "C" fn Ping_get_ponglen(this_ptr: &Ping) -> u16 {
@@ -290,6 +328,23 @@ impl Pong {
                ret
        }
 }
+impl Clone for Pong {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
+                       is_owned: true,
+               }
+       }
+}
+#[allow(unused)]
+/// Used only if an object of this type is returned as a trait impl by a method
+pub(crate) extern "C" fn Pong_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativePong)).clone() })) as *mut c_void
+}
+#[no_mangle]
+pub extern "C" fn Pong_clone(orig: &Pong) -> Pong {
+       Pong { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The pong packet size.
 /// This field is not sent on the wire. byteslen zeros are sent.
 #[no_mangle]
@@ -361,6 +416,10 @@ impl Clone for OpenChannel {
 pub(crate) extern "C" fn OpenChannel_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeOpenChannel)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn OpenChannel_clone(orig: &OpenChannel) -> OpenChannel {
+       OpenChannel { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The genesis hash of the blockchain where the channel is to be opened
 #[no_mangle]
 pub extern "C" fn OpenChannel_get_chain_hash(this_ptr: &OpenChannel) -> *const [u8; 32] {
@@ -610,6 +669,10 @@ impl Clone for AcceptChannel {
 pub(crate) extern "C" fn AcceptChannel_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeAcceptChannel)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn AcceptChannel_clone(orig: &AcceptChannel) -> AcceptChannel {
+       AcceptChannel { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// A temporary channel ID, until the funding outpoint is announced
 #[no_mangle]
 pub extern "C" fn AcceptChannel_get_temporary_channel_id(this_ptr: &AcceptChannel) -> *const [u8; 32] {
@@ -815,6 +878,10 @@ impl Clone for FundingCreated {
 pub(crate) extern "C" fn FundingCreated_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeFundingCreated)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn FundingCreated_clone(orig: &FundingCreated) -> FundingCreated {
+       FundingCreated { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// A temporary channel ID, until the funding is established
 #[no_mangle]
 pub extern "C" fn FundingCreated_get_temporary_channel_id(this_ptr: &FundingCreated) -> *const [u8; 32] {
@@ -920,6 +987,10 @@ impl Clone for FundingSigned {
 pub(crate) extern "C" fn FundingSigned_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeFundingSigned)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn FundingSigned_clone(orig: &FundingSigned) -> FundingSigned {
+       FundingSigned { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn FundingSigned_get_channel_id(this_ptr: &FundingSigned) -> *const [u8; 32] {
@@ -1001,6 +1072,10 @@ impl Clone for FundingLocked {
 pub(crate) extern "C" fn FundingLocked_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeFundingLocked)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn FundingLocked_clone(orig: &FundingLocked) -> FundingLocked {
+       FundingLocked { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn FundingLocked_get_channel_id(this_ptr: &FundingLocked) -> *const [u8; 32] {
@@ -1082,6 +1157,10 @@ impl Clone for Shutdown {
 pub(crate) extern "C" fn Shutdown_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeShutdown)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn Shutdown_clone(orig: &Shutdown) -> Shutdown {
+       Shutdown { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn Shutdown_get_channel_id(this_ptr: &Shutdown) -> *const [u8; 32] {
@@ -1165,6 +1244,10 @@ impl Clone for ClosingSigned {
 pub(crate) extern "C" fn ClosingSigned_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeClosingSigned)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ClosingSigned_clone(orig: &ClosingSigned) -> ClosingSigned {
+       ClosingSigned { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn ClosingSigned_get_channel_id(this_ptr: &ClosingSigned) -> *const [u8; 32] {
@@ -1258,6 +1341,10 @@ impl Clone for UpdateAddHTLC {
 pub(crate) extern "C" fn UpdateAddHTLC_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUpdateAddHTLC)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UpdateAddHTLC_clone(orig: &UpdateAddHTLC) -> UpdateAddHTLC {
+       UpdateAddHTLC { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn UpdateAddHTLC_get_channel_id(this_ptr: &UpdateAddHTLC) -> *const [u8; 32] {
@@ -1364,6 +1451,10 @@ impl Clone for UpdateFulfillHTLC {
 pub(crate) extern "C" fn UpdateFulfillHTLC_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUpdateFulfillHTLC)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UpdateFulfillHTLC_clone(orig: &UpdateFulfillHTLC) -> UpdateFulfillHTLC {
+       UpdateFulfillHTLC { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn UpdateFulfillHTLC_get_channel_id(this_ptr: &UpdateFulfillHTLC) -> *const [u8; 32] {
@@ -1457,6 +1548,10 @@ impl Clone for UpdateFailHTLC {
 pub(crate) extern "C" fn UpdateFailHTLC_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUpdateFailHTLC)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UpdateFailHTLC_clone(orig: &UpdateFailHTLC) -> UpdateFailHTLC {
+       UpdateFailHTLC { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn UpdateFailHTLC_get_channel_id(this_ptr: &UpdateFailHTLC) -> *const [u8; 32] {
@@ -1530,6 +1625,10 @@ impl Clone for UpdateFailMalformedHTLC {
 pub(crate) extern "C" fn UpdateFailMalformedHTLC_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUpdateFailMalformedHTLC)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UpdateFailMalformedHTLC_clone(orig: &UpdateFailMalformedHTLC) -> UpdateFailMalformedHTLC {
+       UpdateFailMalformedHTLC { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn UpdateFailMalformedHTLC_get_channel_id(this_ptr: &UpdateFailMalformedHTLC) -> *const [u8; 32] {
@@ -1614,6 +1713,10 @@ impl Clone for CommitmentSigned {
 pub(crate) extern "C" fn CommitmentSigned_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeCommitmentSigned)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn CommitmentSigned_clone(orig: &CommitmentSigned) -> CommitmentSigned {
+       CommitmentSigned { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn CommitmentSigned_get_channel_id(this_ptr: &CommitmentSigned) -> *const [u8; 32] {
@@ -1703,6 +1806,10 @@ impl Clone for RevokeAndACK {
 pub(crate) extern "C" fn RevokeAndACK_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRevokeAndACK)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn RevokeAndACK_clone(orig: &RevokeAndACK) -> RevokeAndACK {
+       RevokeAndACK { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn RevokeAndACK_get_channel_id(this_ptr: &RevokeAndACK) -> *const [u8; 32] {
@@ -1796,6 +1903,10 @@ impl Clone for UpdateFee {
 pub(crate) extern "C" fn UpdateFee_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUpdateFee)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UpdateFee_clone(orig: &UpdateFee) -> UpdateFee {
+       UpdateFee { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn UpdateFee_get_channel_id(this_ptr: &UpdateFee) -> *const [u8; 32] {
@@ -1880,6 +1991,10 @@ impl Clone for DataLossProtect {
 pub(crate) extern "C" fn DataLossProtect_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeDataLossProtect)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn DataLossProtect_clone(orig: &DataLossProtect) -> DataLossProtect {
+       DataLossProtect { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Proof that the sender knows the per-commitment secret of a specific commitment transaction
 /// belonging to the recipient
 #[no_mangle]
@@ -1963,6 +2078,10 @@ impl Clone for ChannelReestablish {
 pub(crate) extern "C" fn ChannelReestablish_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelReestablish)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ChannelReestablish_clone(orig: &ChannelReestablish) -> ChannelReestablish {
+       ChannelReestablish { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn ChannelReestablish_get_channel_id(this_ptr: &ChannelReestablish) -> *const [u8; 32] {
@@ -2047,6 +2166,10 @@ impl Clone for AnnouncementSignatures {
 pub(crate) extern "C" fn AnnouncementSignatures_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeAnnouncementSignatures)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn AnnouncementSignatures_clone(orig: &AnnouncementSignatures) -> AnnouncementSignatures {
+       AnnouncementSignatures { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The channel ID
 #[no_mangle]
 pub extern "C" fn AnnouncementSignatures_get_channel_id(this_ptr: &AnnouncementSignatures) -> *const [u8; 32] {
@@ -2280,6 +2403,10 @@ impl NetAddress {
 }
 #[no_mangle]
 pub extern "C" fn NetAddress_free(this_ptr: NetAddress) { }
+#[no_mangle]
+pub extern "C" fn NetAddress_clone(orig: &NetAddress) -> NetAddress {
+       orig.clone()
+}
 
 use lightning::ln::msgs::UnsignedNodeAnnouncement as nativeUnsignedNodeAnnouncementImport;
 type nativeUnsignedNodeAnnouncement = nativeUnsignedNodeAnnouncementImport;
@@ -2331,6 +2458,10 @@ impl Clone for UnsignedNodeAnnouncement {
 pub(crate) extern "C" fn UnsignedNodeAnnouncement_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUnsignedNodeAnnouncement)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UnsignedNodeAnnouncement_clone(orig: &UnsignedNodeAnnouncement) -> UnsignedNodeAnnouncement {
+       UnsignedNodeAnnouncement { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The advertised features
 #[no_mangle]
 pub extern "C" fn UnsignedNodeAnnouncement_get_features(this_ptr: &UnsignedNodeAnnouncement) -> crate::ln::features::NodeFeatures {
@@ -2447,6 +2578,10 @@ impl Clone for NodeAnnouncement {
 pub(crate) extern "C" fn NodeAnnouncement_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeNodeAnnouncement)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn NodeAnnouncement_clone(orig: &NodeAnnouncement) -> NodeAnnouncement {
+       NodeAnnouncement { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The signature by the node key
 #[no_mangle]
 pub extern "C" fn NodeAnnouncement_get_signature(this_ptr: &NodeAnnouncement) -> crate::c_types::Signature {
@@ -2528,6 +2663,10 @@ impl Clone for UnsignedChannelAnnouncement {
 pub(crate) extern "C" fn UnsignedChannelAnnouncement_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUnsignedChannelAnnouncement)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UnsignedChannelAnnouncement_clone(orig: &UnsignedChannelAnnouncement) -> UnsignedChannelAnnouncement {
+       UnsignedChannelAnnouncement { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The advertised channel features
 #[no_mangle]
 pub extern "C" fn UnsignedChannelAnnouncement_get_features(this_ptr: &UnsignedChannelAnnouncement) -> crate::ln::features::ChannelFeatures {
@@ -2656,6 +2795,10 @@ impl Clone for ChannelAnnouncement {
 pub(crate) extern "C" fn ChannelAnnouncement_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelAnnouncement)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ChannelAnnouncement_clone(orig: &ChannelAnnouncement) -> ChannelAnnouncement {
+       ChannelAnnouncement { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Authentication of the announcement by the first public node
 #[no_mangle]
 pub extern "C" fn ChannelAnnouncement_get_node_signature_1(this_ptr: &ChannelAnnouncement) -> crate::c_types::Signature {
@@ -2773,6 +2916,10 @@ impl Clone for UnsignedChannelUpdate {
 pub(crate) extern "C" fn UnsignedChannelUpdate_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUnsignedChannelUpdate)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UnsignedChannelUpdate_clone(orig: &UnsignedChannelUpdate) -> UnsignedChannelUpdate {
+       UnsignedChannelUpdate { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The genesis hash of the blockchain where the channel is to be opened
 #[no_mangle]
 pub extern "C" fn UnsignedChannelUpdate_get_chain_hash(this_ptr: &UnsignedChannelUpdate) -> *const [u8; 32] {
@@ -2912,6 +3059,10 @@ impl Clone for ChannelUpdate {
 pub(crate) extern "C" fn ChannelUpdate_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelUpdate)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ChannelUpdate_clone(orig: &ChannelUpdate) -> ChannelUpdate {
+       ChannelUpdate { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// A signature of the channel update
 #[no_mangle]
 pub extern "C" fn ChannelUpdate_get_signature(this_ptr: &ChannelUpdate) -> crate::c_types::Signature {
@@ -2996,6 +3147,10 @@ impl Clone for QueryChannelRange {
 pub(crate) extern "C" fn QueryChannelRange_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeQueryChannelRange)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn QueryChannelRange_clone(orig: &QueryChannelRange) -> QueryChannelRange {
+       QueryChannelRange { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The genesis hash of the blockchain being queried
 #[no_mangle]
 pub extern "C" fn QueryChannelRange_get_chain_hash(this_ptr: &QueryChannelRange) -> *const [u8; 32] {
@@ -3095,6 +3250,10 @@ impl Clone for ReplyChannelRange {
 pub(crate) extern "C" fn ReplyChannelRange_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeReplyChannelRange)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ReplyChannelRange_clone(orig: &ReplyChannelRange) -> ReplyChannelRange {
+       ReplyChannelRange { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The genesis hash of the blockchain being queried
 #[no_mangle]
 pub extern "C" fn ReplyChannelRange_get_chain_hash(this_ptr: &ReplyChannelRange) -> *const [u8; 32] {
@@ -3217,6 +3376,10 @@ impl Clone for QueryShortChannelIds {
 pub(crate) extern "C" fn QueryShortChannelIds_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeQueryShortChannelIds)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn QueryShortChannelIds_clone(orig: &QueryShortChannelIds) -> QueryShortChannelIds {
+       QueryShortChannelIds { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The genesis hash of the blockchain being queried
 #[no_mangle]
 pub extern "C" fn QueryShortChannelIds_get_chain_hash(this_ptr: &QueryShortChannelIds) -> *const [u8; 32] {
@@ -3297,6 +3460,10 @@ impl Clone for ReplyShortChannelIdsEnd {
 pub(crate) extern "C" fn ReplyShortChannelIdsEnd_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeReplyShortChannelIdsEnd)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ReplyShortChannelIdsEnd_clone(orig: &ReplyShortChannelIdsEnd) -> ReplyShortChannelIdsEnd {
+       ReplyShortChannelIdsEnd { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The genesis hash of the blockchain that was queried
 #[no_mangle]
 pub extern "C" fn ReplyShortChannelIdsEnd_get_chain_hash(this_ptr: &ReplyShortChannelIdsEnd) -> *const [u8; 32] {
@@ -3382,6 +3549,10 @@ impl Clone for GossipTimestampFilter {
 pub(crate) extern "C" fn GossipTimestampFilter_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeGossipTimestampFilter)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn GossipTimestampFilter_clone(orig: &GossipTimestampFilter) -> GossipTimestampFilter {
+       GossipTimestampFilter { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The genesis hash of the blockchain for channel and node information
 #[no_mangle]
 pub extern "C" fn GossipTimestampFilter_get_chain_hash(this_ptr: &GossipTimestampFilter) -> *const [u8; 32] {
@@ -3517,6 +3688,10 @@ impl ErrorAction {
 }
 #[no_mangle]
 pub extern "C" fn ErrorAction_free(this_ptr: ErrorAction) { }
+#[no_mangle]
+pub extern "C" fn ErrorAction_clone(orig: &ErrorAction) -> ErrorAction {
+       orig.clone()
+}
 
 use lightning::ln::msgs::LightningError as nativeLightningErrorImport;
 type nativeLightningError = nativeLightningErrorImport;
@@ -3637,6 +3812,10 @@ impl Clone for CommitmentUpdate {
 pub(crate) extern "C" fn CommitmentUpdate_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeCommitmentUpdate)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn CommitmentUpdate_clone(orig: &CommitmentUpdate) -> CommitmentUpdate {
+       CommitmentUpdate { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// update_add_htlc messages which should be sent
 #[no_mangle]
 pub extern "C" fn CommitmentUpdate_set_update_add_htlcs(this_ptr: &mut CommitmentUpdate, mut val: crate::c_types::derived::CVec_UpdateAddHTLCZ) {
@@ -3827,6 +4006,10 @@ impl HTLCFailChannelUpdate {
 }
 #[no_mangle]
 pub extern "C" fn HTLCFailChannelUpdate_free(this_ptr: HTLCFailChannelUpdate) { }
+#[no_mangle]
+pub extern "C" fn HTLCFailChannelUpdate_clone(orig: &HTLCFailChannelUpdate) -> HTLCFailChannelUpdate {
+       orig.clone()
+}
 /// A trait to describe an object which can receive channel messages.
 ///
 /// Messages MAY be called in parallel when they originate from different their_node_ids, however
index e4c8b59b1b45a78018335434b07ca609fe574cf0..50e1c3696a8d222e0017a2e6309e8fc2408c0f02 100644 (file)
@@ -118,29 +118,33 @@ pub struct SocketDescriptor {
        /// though races may occur whereby disconnect_socket is called after a call to
        /// socket_disconnected but prior to socket_disconnected returning.
        pub disconnect_socket: extern "C" fn (this_arg: *mut c_void),
-       pub eq: extern "C" fn (this_arg: *const c_void, other_arg: *const c_void) -> bool,
+       pub eq: extern "C" fn (this_arg: *const c_void, other_arg: &SocketDescriptor) -> bool,
        pub hash: extern "C" fn (this_arg: *const c_void) -> u64,
        pub clone: Option<extern "C" fn (this_arg: *const c_void) -> *mut c_void>,
        pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
 }
 impl std::cmp::Eq for SocketDescriptor {}
 impl std::cmp::PartialEq for SocketDescriptor {
-       fn eq(&self, o: &Self) -> bool { (self.eq)(self.this_arg, o.this_arg) }
+       fn eq(&self, o: &Self) -> bool { (self.eq)(self.this_arg, o) }
 }
 impl std::hash::Hash for SocketDescriptor {
        fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) { hasher.write_u64((self.hash)(self.this_arg)) }
 }
+#[no_mangle]
+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(),
+       }
+}
 impl Clone for SocketDescriptor {
        fn clone(&self) -> Self {
-               Self {
-               this_arg: if let Some(f) = self.clone { (f)(self.this_arg) } else { self.this_arg },
-                       send_data: self.send_data.clone(),
-                       disconnect_socket: self.disconnect_socket.clone(),
-                       eq: self.eq.clone(),
-                       hash: self.hash.clone(),
-                       clone: self.clone.clone(),
-                       free: self.free.clone(),
-               }
+               SocketDescriptor_clone(self)
        }
 }
 
index c2930f0f335a12ff575b854e1fd104c5e59df6aa..11eb92a363a1dca996418ee29399361feb3ab7a0 100644 (file)
@@ -517,6 +517,10 @@ impl Clone for RoutingFees {
 pub(crate) extern "C" fn RoutingFees_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRoutingFees)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn RoutingFees_clone(orig: &RoutingFees) -> RoutingFees {
+       RoutingFees { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Flat routing fee in satoshis
 #[no_mangle]
 pub extern "C" fn RoutingFees_get_base_msat(this_ptr: &RoutingFees) -> u32 {
index 2195fe47daa17e7aac00620535e30c98232fb9f5..8be9528330d2ae41b1b8ba87704690d150b5277a 100644 (file)
@@ -58,6 +58,10 @@ impl Clone for RouteHop {
 pub(crate) extern "C" fn RouteHop_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRouteHop)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn RouteHop_clone(orig: &RouteHop) -> RouteHop {
+       RouteHop { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The node_id of the node at this hop.
 #[no_mangle]
 pub extern "C" fn RouteHop_get_pubkey(this_ptr: &RouteHop) -> crate::c_types::PublicKey {
@@ -194,6 +198,10 @@ impl Clone for Route {
 pub(crate) extern "C" fn Route_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRoute)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn Route_clone(orig: &Route) -> Route {
+       Route { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The list of routes taken for a single (potentially-)multi-part payment. The pubkey of the
 /// last RouteHop in each path must be the same.
 /// Each entry represents a list of hops, NOT INCLUDING our own, where the last hop is the
@@ -263,6 +271,23 @@ impl RouteHint {
                ret
        }
 }
+impl Clone for RouteHint {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
+                       is_owned: true,
+               }
+       }
+}
+#[allow(unused)]
+/// Used only if an object of this type is returned as a trait impl by a method
+pub(crate) extern "C" fn RouteHint_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRouteHint)).clone() })) as *mut c_void
+}
+#[no_mangle]
+pub extern "C" fn RouteHint_clone(orig: &RouteHint) -> RouteHint {
+       RouteHint { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// The node_id of the non-target end of the route
 #[no_mangle]
 pub extern "C" fn RouteHint_get_src_node_id(this_ptr: &RouteHint) -> crate::c_types::PublicKey {
index 30a42708f705f7b65a865da9f298c3c97ab8961b..346ddc344a1a70f174cabc29c0e6b63767dc9f74 100644 (file)
@@ -58,6 +58,10 @@ impl Clone for ChannelHandshakeConfig {
 pub(crate) extern "C" fn ChannelHandshakeConfig_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelHandshakeConfig)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ChannelHandshakeConfig_clone(orig: &ChannelHandshakeConfig) -> ChannelHandshakeConfig {
+       ChannelHandshakeConfig { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Confirmations we will wait for before considering the channel locked in.
 /// Applied only for inbound channels (see ChannelHandshakeLimits::max_minimum_depth for the
 /// equivalent limit applied to outbound channels).
@@ -208,6 +212,10 @@ impl Clone for ChannelHandshakeLimits {
 pub(crate) extern "C" fn ChannelHandshakeLimits_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelHandshakeLimits)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ChannelHandshakeLimits_clone(orig: &ChannelHandshakeLimits) -> ChannelHandshakeLimits {
+       ChannelHandshakeLimits { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Minimum allowed satoshis when a channel is funded, this is supplied by the sender and so
 /// only applies to inbound channels.
 ///
@@ -477,6 +485,10 @@ impl Clone for ChannelConfig {
 pub(crate) extern "C" fn ChannelConfig_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelConfig)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn ChannelConfig_clone(orig: &ChannelConfig) -> ChannelConfig {
+       ChannelConfig { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Amount (in millionths of a satoshi) the channel will charge per transferred satoshi.
 /// This may be allowed to change at runtime in a later update, however doing so must result in
 /// update messages sent to notify all nodes of our updated relay fee.
@@ -638,6 +650,10 @@ impl Clone for UserConfig {
 pub(crate) extern "C" fn UserConfig_clone_void(this_ptr: *const c_void) -> *mut c_void {
        Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUserConfig)).clone() })) as *mut c_void
 }
+#[no_mangle]
+pub extern "C" fn UserConfig_clone(orig: &UserConfig) -> UserConfig {
+       UserConfig { inner: Box::into_raw(Box::new(unsafe { &*orig.inner }.clone())), is_owned: true }
+}
 /// Channel config that we propose to our counterparty.
 #[no_mangle]
 pub extern "C" fn UserConfig_get_own_channel_config(this_ptr: &UserConfig) -> crate::util::config::ChannelHandshakeConfig {
index 06cb4a7f879ab6318fc9aad25bf2244dfffefdbf..9b0e757de971217a60fdb9925872f3a1bbd68f6a 100644 (file)
@@ -160,3 +160,7 @@ impl APIError {
 }
 #[no_mangle]
 pub extern "C" fn APIError_free(this_ptr: APIError) { }
+#[no_mangle]
+pub extern "C" fn APIError_clone(orig: &APIError) -> APIError {
+       orig.clone()
+}
index db8ac33f8f60fbee426aa72a2e64a6d00f0746d9..e596774b6c137253f0216c365299a32d58c1bef4 100644 (file)
@@ -308,6 +308,10 @@ impl Event {
 }
 #[no_mangle]
 pub extern "C" fn Event_free(this_ptr: Event) { }
+#[no_mangle]
+pub extern "C" fn Event_clone(orig: &Event) -> Event {
+       orig.clone()
+}
 /// An event generated by ChannelManager which indicates a message should be sent to a peer (or
 /// broadcast to most peers).
 /// These events are handled by PeerManager::process_events if you are using a PeerManager.
@@ -859,6 +863,10 @@ impl MessageSendEvent {
 }
 #[no_mangle]
 pub extern "C" fn MessageSendEvent_free(this_ptr: MessageSendEvent) { }
+#[no_mangle]
+pub extern "C" fn MessageSendEvent_clone(orig: &MessageSendEvent) -> MessageSendEvent {
+       orig.clone()
+}
 /// A trait indicating an object may generate message send events
 #[repr(C)]
 pub struct MessageSendEventsProvider {
index ae20abbb6aec25c44a780dc1dc096ee76b4a089d..8a1fbb15d54340e37dccf5b0f6592a6020659681 100644 (file)
@@ -74,6 +74,10 @@ impl Level {
                }
        }
 }
+#[no_mangle]
+pub extern "C" fn Level_clone(orig: &Level) -> Level {
+       orig.clone()
+}
 /// Returns the most verbose logging level.
 #[must_use]
 #[no_mangle]
index 469837f07ed6cf8f790bd4abe2315ed3d7f43b49..13a0a883140994de21444992134492acedf0377f 100644 (file)
@@ -194,11 +194,18 @@ where C::Target: chain::Filter,
                match monitors.get_mut(&funding_txo) {
                        None => {
                                log_error!(self.logger, "Failed to update channel monitor: no such monitor registered");
+
+                               // We should never ever trigger this from within ChannelManager. Technically a
+                               // user could use this object with some proxying in between which makes this
+                               // possible, but in tests and fuzzing, this should be a panic.
+                               #[cfg(any(test, feature = "fuzztarget"))]
+                               panic!("ChannelManager generated a channel update for a channel that was not yet registered!");
+                               #[cfg(not(any(test, feature = "fuzztarget")))]
                                Err(ChannelMonitorUpdateErr::PermanentFailure)
                        },
                        Some(orig_monitor) => {
                                log_trace!(self.logger, "Updating Channel Monitor for channel {}", log_funding_info!(orig_monitor));
-                               let update_res = orig_monitor.update_monitor(&update, &self.broadcaster, &self.logger);
+                               let update_res = orig_monitor.update_monitor(&update, &self.broadcaster, &self.fee_estimator, &self.logger);
                                if let Err(e) = &update_res {
                                        log_error!(self.logger, "Failed to update channel monitor: {:?}", e);
                                }
index 889dfa211ee78d167dbad2229ffcaf7dc82d1d4c..c3382caaea4f8f199b4bf40843788db682c5e6bf 100644 (file)
@@ -64,14 +64,29 @@ pub struct ChannelMonitorUpdate {
        pub(crate) updates: Vec<ChannelMonitorUpdateStep>,
        /// The sequence number of this update. Updates *must* be replayed in-order according to this
        /// sequence number (and updates may panic if they are not). The update_id values are strictly
-       /// increasing and increase by one for each new update.
+       /// increasing and increase by one for each new update, with one exception specified below.
        ///
        /// This sequence number is also used to track up to which points updates which returned
        /// ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
        /// ChannelMonitor when ChannelManager::channel_monitor_updated is called.
+       ///
+       /// The only instance where update_id values are not strictly increasing is the case where we
+       /// allow post-force-close updates with a special update ID of [`CLOSED_CHANNEL_UPDATE_ID`]. See
+       /// its docs for more details.
+       ///
+       /// [`CLOSED_CHANNEL_UPDATE_ID`]: constant.CLOSED_CHANNEL_UPDATE_ID.html
        pub update_id: u64,
 }
 
+/// If:
+///    (1) a channel has been force closed and
+///    (2) we receive a preimage from a forward link that allows us to spend an HTLC output on
+///        this channel's (the backward link's) broadcasted commitment transaction
+/// then we allow the `ChannelManager` to send a `ChannelMonitorUpdate` with this update ID,
+/// with the update providing said payment preimage. No other update types are allowed after
+/// force-close.
+pub const CLOSED_CHANNEL_UPDATE_ID: u64 = std::u64::MAX;
+
 impl Writeable for ChannelMonitorUpdate {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
                self.update_id.write(w)?;
@@ -164,7 +179,7 @@ pub enum ChannelMonitorUpdateErr {
 pub struct MonitorUpdateError(pub &'static str);
 
 /// An event to be processed by the ChannelManager.
-#[derive(PartialEq)]
+#[derive(Clone, PartialEq)]
 pub enum MonitorEvent {
        /// A monitor event containing an HTLCUpdate.
        HTLCEvent(HTLCUpdate),
@@ -1144,8 +1159,47 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
 
        /// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all
        /// commitment_tx_infos which contain the payment hash have been revoked.
-       pub(crate) fn provide_payment_preimage(&mut self, payment_hash: &PaymentHash, payment_preimage: &PaymentPreimage) {
+       pub(crate) fn provide_payment_preimage<B: Deref, F: Deref, L: Deref>(&mut self, payment_hash: &PaymentHash, payment_preimage: &PaymentPreimage, broadcaster: &B, fee_estimator: &F, logger: &L)
+       where B::Target: BroadcasterInterface,
+                   F::Target: FeeEstimator,
+                   L::Target: Logger,
+       {
                self.payment_preimages.insert(payment_hash.clone(), payment_preimage.clone());
+
+               // If the channel is force closed, try to claim the output from this preimage.
+               // First check if a counterparty commitment transaction has been broadcasted:
+               macro_rules! claim_htlcs {
+                       ($commitment_number: expr, $txid: expr) => {
+                               let htlc_claim_reqs = self.get_counterparty_htlc_output_claim_reqs($commitment_number, $txid, None);
+                               self.onchain_tx_handler.update_claims_view(&Vec::new(), htlc_claim_reqs, None, broadcaster, fee_estimator, logger);
+                       }
+               }
+               if let Some(txid) = self.current_counterparty_commitment_txid {
+                       if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
+                               claim_htlcs!(*commitment_number, txid);
+                               return;
+                       }
+               }
+               if let Some(txid) = self.prev_counterparty_commitment_txid {
+                       if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
+                               claim_htlcs!(*commitment_number, txid);
+                               return;
+                       }
+               }
+
+               // Then if a holder commitment transaction has been seen on-chain, broadcast transactions
+               // claiming the HTLC output from each of the holder commitment transactions.
+               // Note that we can't just use `self.holder_tx_signed`, because that only covers the case where
+               // *we* sign a holder commitment transaction, not when e.g. a watchtower broadcasts one of our
+               // holder commitment transactions.
+               if self.broadcasted_holder_revokable_script.is_some() {
+                       let (claim_reqs, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx);
+                       self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, None, broadcaster, fee_estimator, logger);
+                       if let Some(ref tx) = self.prev_holder_signed_commitment_tx {
+                               let (claim_reqs, _) = self.get_broadcasted_holder_claims(&tx);
+                               self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, None, broadcaster, fee_estimator, logger);
+                       }
+               }
        }
 
        pub(crate) fn broadcast_latest_holder_commitment_txn<B: Deref, L: Deref>(&mut self, broadcaster: &B, logger: &L)
@@ -1162,26 +1216,45 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
        /// itself.
        ///
        /// panics if the given update is not the next update by update_id.
-       pub fn update_monitor<B: Deref, L: Deref>(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, logger: &L) -> Result<(), MonitorUpdateError>
-               where B::Target: BroadcasterInterface,
-                                       L::Target: Logger,
+       pub fn update_monitor<B: Deref, F: Deref, L: Deref>(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: &F, logger: &L) -> Result<(), MonitorUpdateError>
+       where B::Target: BroadcasterInterface,
+                   F::Target: FeeEstimator,
+                   L::Target: Logger,
        {
-               if self.latest_update_id + 1 != updates.update_id {
+               // ChannelMonitor updates may be applied after force close if we receive a
+               // preimage for a broadcasted commitment transaction HTLC output that we'd
+               // like to claim on-chain. If this is the case, we no longer have guaranteed
+               // access to the monitor's update ID, so we use a sentinel value instead.
+               if updates.update_id == CLOSED_CHANNEL_UPDATE_ID {
+                       match updates.updates[0] {
+                               ChannelMonitorUpdateStep::PaymentPreimage { .. } => {},
+                               _ => panic!("Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage"),
+                       }
+                       assert_eq!(updates.updates.len(), 1);
+               } else if self.latest_update_id + 1 != updates.update_id {
                        panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!");
                }
                for update in updates.updates.iter() {
                        match update {
                                ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs } => {
+                                       log_trace!(logger, "Updating ChannelMonitor with latest holder commitment transaction info");
                                        if self.lockdown_from_offchain { panic!(); }
                                        self.provide_latest_holder_commitment_tx_info(commitment_tx.clone(), htlc_outputs.clone())?
                                },
-                               ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
-                                       self.provide_latest_counterparty_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs.clone(), *commitment_number, *their_revocation_point, logger),
-                               ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
-                                       self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage),
-                               ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } =>
-                                       self.provide_secret(*idx, *secret)?,
+                               ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } => {
+                                       log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
+                                       self.provide_latest_counterparty_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs.clone(), *commitment_number, *their_revocation_point, logger)
+                               },
+                               ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => {
+                                       log_trace!(logger, "Updating ChannelMonitor with payment preimage");
+                                       self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage, broadcaster, fee_estimator, logger)
+                               },
+                               ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => {
+                                       log_trace!(logger, "Updating ChannelMonitor with commitment secret");
+                                       self.provide_secret(*idx, *secret)?
+                               },
                                ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => {
+                                       log_trace!(logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}", should_broadcast);
                                        self.lockdown_from_offchain = true;
                                        if *should_broadcast {
                                                self.broadcast_latest_holder_commitment_txn(broadcaster, logger);
@@ -1425,39 +1498,55 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                                check_htlc_fails!(txid, "previous", 'prev_loop);
                        }
 
+                       let htlc_claim_reqs = self.get_counterparty_htlc_output_claim_reqs(commitment_number, commitment_txid, Some(tx));
+                       for req in htlc_claim_reqs {
+                               claimable_outpoints.push(req);
+                       }
+
+               }
+               (claimable_outpoints, (commitment_txid, watch_outputs))
+       }
+
+       fn get_counterparty_htlc_output_claim_reqs(&self, commitment_number: u64, commitment_txid: Txid, tx: Option<&Transaction>) -> Vec<ClaimRequest> {
+               let mut claims = Vec::new();
+               if let Some(htlc_outputs) = self.counterparty_claimable_outpoints.get(&commitment_txid) {
                        if let Some(revocation_points) = self.their_cur_revocation_points {
                                let revocation_point_option =
+                                       // If the counterparty commitment tx is the latest valid state, use their latest
+                                       // per-commitment point
                                        if revocation_points.0 == commitment_number { Some(&revocation_points.1) }
                                        else if let Some(point) = revocation_points.2.as_ref() {
+                                               // If counterparty commitment tx is the state previous to the latest valid state, use
+                                               // their previous per-commitment point (non-atomicity of revocation means it's valid for
+                                               // them to temporarily have two valid commitment txns from our viewpoint)
                                                if revocation_points.0 == commitment_number + 1 { Some(point) } else { None }
                                        } else { None };
                                if let Some(revocation_point) = revocation_point_option {
-                                       self.counterparty_payment_script = {
-                                               // Note that the Network here is ignored as we immediately drop the address for the
-                                               // script_pubkey version
-                                               let payment_hash160 = WPubkeyHash::hash(&self.keys.pubkeys().payment_point.serialize());
-                                               Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_hash160[..]).into_script()
-                                       };
-
-                                       // Then, try to find htlc outputs
-                                       for (_, &(ref htlc, _)) in per_commitment_data.iter().enumerate() {
+                                       for (_, &(ref htlc, _)) in htlc_outputs.iter().enumerate() {
                                                if let Some(transaction_output_index) = htlc.transaction_output_index {
-                                                       if transaction_output_index as usize >= tx.output.len() ||
-                                                                       tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
-                                                               return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user
+                                                       if let Some(transaction) = tx {
+                                                               if transaction_output_index as usize >= transaction.output.len() ||
+                                                                       transaction.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
+                                                                               return claims; // Corrupted per_commitment_data, fuck this user
+                                                                       }
                                                        }
-                                                       let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
+                                                       let preimage =
+                                                               if htlc.offered {
+                                                                       if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) {
+                                                                               Some(*p)
+                                                                       } else { None }
+                                                               } else { None };
                                                        let aggregable = if !htlc.offered { false } else { true };
                                                        if preimage.is_some() || !htlc.offered {
                                                                let witness_data = InputMaterial::CounterpartyHTLC { per_commitment_point: *revocation_point, counterparty_delayed_payment_base_key: self.counterparty_tx_cache.counterparty_delayed_payment_base_key, counterparty_htlc_base_key: self.counterparty_tx_cache.counterparty_htlc_base_key, preimage, htlc: htlc.clone() };
-                                                               claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
+                                                               claims.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
                                                        }
                                                }
                                        }
                                }
                        }
                }
-               (claimable_outpoints, (commitment_txid, watch_outputs))
+               claims
        }
 
        /// Attempts to claim a counterparty HTLC-Success/HTLC-Timeout's outputs using the revocation key
@@ -1487,9 +1576,11 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                (claimable_outpoints, Some((htlc_txid, outputs)))
        }
 
-       fn broadcast_by_holder_state(&self, commitment_tx: &Transaction, holder_tx: &HolderSignedTx) -> (Vec<ClaimRequest>, Vec<(u32, TxOut)>, Option<(Script, PublicKey, PublicKey)>) {
+       // Returns (1) `ClaimRequest`s that can be given to the OnChainTxHandler, so that the handler can
+       // broadcast transactions claiming holder HTLC commitment outputs and (2) a holder revokable
+       // script so we can detect whether a holder transaction has been seen on-chain.
+       fn get_broadcasted_holder_claims(&self, holder_tx: &HolderSignedTx) -> (Vec<ClaimRequest>, Option<(Script, PublicKey, PublicKey)>) {
                let mut claim_requests = Vec::with_capacity(holder_tx.htlc_outputs.len());
-               let mut watch_outputs = Vec::with_capacity(holder_tx.htlc_outputs.len());
 
                let redeemscript = chan_utils::get_revokeable_redeemscript(&holder_tx.revocation_key, self.on_holder_tx_csv, &holder_tx.delayed_payment_key);
                let broadcasted_holder_revokable_script = Some((redeemscript.to_v0_p2wsh(), holder_tx.per_commitment_point.clone(), holder_tx.revocation_key.clone()));
@@ -1508,11 +1599,21 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                                                        } else { None },
                                                amount: htlc.amount_msat,
                                }});
-                               watch_outputs.push((transaction_output_index, commitment_tx.output[transaction_output_index as usize].clone()));
                        }
                }
 
-               (claim_requests, watch_outputs, broadcasted_holder_revokable_script)
+               (claim_requests, broadcasted_holder_revokable_script)
+       }
+
+       // Returns holder HTLC outputs to watch and react to in case of spending.
+       fn get_broadcasted_holder_watch_outputs(&self, holder_tx: &HolderSignedTx, commitment_tx: &Transaction) -> Vec<(u32, TxOut)> {
+               let mut watch_outputs = Vec::with_capacity(holder_tx.htlc_outputs.len());
+               for &(ref htlc, _, _) in holder_tx.htlc_outputs.iter() {
+                       if let Some(transaction_output_index) = htlc.transaction_output_index {
+                               watch_outputs.push((transaction_output_index, commitment_tx.output[transaction_output_index as usize].clone()));
+                       }
+               }
+               watch_outputs
        }
 
        /// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet)
@@ -1547,10 +1648,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                }
 
                macro_rules! append_onchain_update {
-                       ($updates: expr) => {
+                       ($updates: expr, $to_watch: expr) => {
                                claim_requests = $updates.0;
-                               watch_outputs.append(&mut $updates.1);
-                               self.broadcasted_holder_revokable_script = $updates.2;
+                               self.broadcasted_holder_revokable_script = $updates.1;
+                               watch_outputs.append(&mut $to_watch);
                        }
                }
 
@@ -1560,14 +1661,16 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                if self.current_holder_commitment_tx.txid == commitment_txid {
                        is_holder_tx = true;
                        log_trace!(logger, "Got latest holder commitment tx broadcast, searching for available HTLCs to claim");
-                       let mut res = self.broadcast_by_holder_state(tx, &self.current_holder_commitment_tx);
-                       append_onchain_update!(res);
+                       let res = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx);
+                       let mut to_watch = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, tx);
+                       append_onchain_update!(res, to_watch);
                } else if let &Some(ref holder_tx) = &self.prev_holder_signed_commitment_tx {
                        if holder_tx.txid == commitment_txid {
                                is_holder_tx = true;
                                log_trace!(logger, "Got previous holder commitment tx broadcast, searching for available HTLCs to claim");
-                               let mut res = self.broadcast_by_holder_state(tx, holder_tx);
-                               append_onchain_update!(res);
+                               let res = self.get_broadcasted_holder_claims(holder_tx);
+                               let mut to_watch = self.get_broadcasted_holder_watch_outputs(holder_tx, tx);
+                               append_onchain_update!(res, to_watch);
                        }
                }
 
@@ -1735,7 +1838,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                        self.pending_monitor_events.push(MonitorEvent::CommitmentTxBroadcasted(self.funding_info.0));
                        if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript) {
                                self.holder_tx_signed = true;
-                               let (mut new_outpoints, new_outputs, _) = self.broadcast_by_holder_state(&commitment_tx, &self.current_holder_commitment_tx);
+                               let (mut new_outpoints, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx);
+                               let new_outputs = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, &commitment_tx);
                                if !new_outputs.is_empty() {
                                        watch_outputs.push((self.current_holder_commitment_tx.txid.clone(), new_outputs));
                                }
@@ -1763,7 +1867,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                        }
                }
 
-               self.onchain_tx_handler.block_connected(&txn_matched, claimable_outpoints, height, &*broadcaster, &*fee_estimator, &*logger);
+               self.onchain_tx_handler.update_claims_view(&txn_matched, claimable_outpoints, Some(height), &&*broadcaster, &&*fee_estimator, &&*logger);
                self.last_block_hash = block_hash;
 
                // Determine new outputs to watch by comparing against previously known outputs to watch,
@@ -2486,16 +2590,18 @@ mod tests {
        use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
        use ln::chan_utils;
        use ln::chan_utils::{HTLCOutputInCommitment, HolderCommitmentTransaction};
-       use util::test_utils::TestLogger;
+       use util::test_utils::{TestLogger, TestBroadcaster, TestFeeEstimator};
        use bitcoin::secp256k1::key::{SecretKey,PublicKey};
        use bitcoin::secp256k1::Secp256k1;
-       use std::sync::Arc;
+       use std::sync::{Arc, Mutex};
        use chain::keysinterface::InMemoryChannelKeys;
 
        #[test]
        fn test_prune_preimages() {
                let secp_ctx = Secp256k1::new();
                let logger = Arc::new(TestLogger::new());
+               let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())});
+               let fee_estimator = Arc::new(TestFeeEstimator { sat_per_kw: 253 });
 
                let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let dummy_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
@@ -2571,7 +2677,7 @@ mod tests {
                monitor.provide_latest_counterparty_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
                monitor.provide_latest_counterparty_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
                for &(ref preimage, ref hash) in preimages.iter() {
-                       monitor.provide_payment_preimage(hash, preimage);
+                       monitor.provide_payment_preimage(hash, preimage, &broadcaster, &fee_estimator, &logger);
                }
 
                // Now provide a secret, pruning preimages 10-15
index 540155a3afbbe9bcbda72fd5d5208887354e3e0b..7b7d511d653e0553e2fb41d44cd97c2a31adf445 100644 (file)
@@ -318,6 +318,7 @@ impl_writeable!(TxCreationKeys, 33*6,
 /// in the signer.
 /// The pre-calculated keys are an optimization, because ChannelKeys has enough
 /// information to re-derive them.
+#[derive(PartialEq, Clone)]
 pub struct PreCalculatedTxCreationKeys(TxCreationKeys);
 
 impl PreCalculatedTxCreationKeys {
index c34fc6a38c28e5ae89a5cd98e094ee7a5348781a..abf2834c26a93d6b020ea095959014c08c963642 100644 (file)
@@ -4016,11 +4016,23 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
                                _ => {}
                        }
                }
+               let funding_txo = if let Some(funding_txo) = self.funding_txo {
+                       // If we haven't yet exchanged funding signatures (ie channel_state < FundingSent),
+                       // returning a channel monitor update here would imply a channel monitor update before
+                       // we even registered the channel monitor to begin with, which is invalid.
+                       // Thus, if we aren't actually at a point where we could conceivably broadcast the
+                       // funding transaction, don't return a funding txo (which prevents providing the
+                       // monitor update to the user, even if we return one).
+                       // See test_duplicate_chan_id and test_pre_lockin_no_chan_closed_update for more.
+                       if self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::ChannelFunded as u32 | ChannelState::ShutdownComplete as u32) != 0 {
+                               Some(funding_txo.clone())
+                       } else { None }
+               } else { None };
 
                self.channel_state = ChannelState::ShutdownComplete as u32;
                self.update_time_counter += 1;
                self.latest_monitor_update_id += 1;
-               (self.funding_txo.clone(), ChannelMonitorUpdate {
+               (funding_txo, ChannelMonitorUpdate {
                        update_id: self.latest_monitor_update_id,
                        updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast }],
                }, dropped_outbound_htlcs)
index b43c98c840392c7b983de276e0867ba5e3baf795..0f5e7f8ad63736dcf5f567f3cd5a9af920a57735 100644 (file)
@@ -37,7 +37,7 @@ use bitcoin::secp256k1;
 use chain;
 use chain::Watch;
 use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
-use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, MonitorEvent};
+use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, ChannelMonitorUpdateErr, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, MonitorEvent, CLOSED_CHANNEL_UPDATE_ID};
 use chain::transaction::{OutPoint, TransactionData};
 use ln::channel::{Channel, ChannelError};
 use ln::features::{InitFeatures, NodeFeatures};
@@ -118,9 +118,15 @@ pub(super) enum PendingHTLCStatus {
 
 pub(super) enum HTLCForwardInfo {
        AddHTLC {
+               forward_info: PendingHTLCInfo,
+
+               // These fields are produced in `forward_htlcs()` and consumed in
+               // `process_pending_htlc_forwards()` for constructing the
+               // `HTLCSource::PreviousHopData` for failed and forwarded
+               // HTLCs.
                prev_short_channel_id: u64,
                prev_htlc_id: u64,
-               forward_info: PendingHTLCInfo,
+               prev_funding_outpoint: OutPoint,
        },
        FailHTLC {
                htlc_id: u64,
@@ -134,6 +140,10 @@ pub(crate) struct HTLCPreviousHopData {
        short_channel_id: u64,
        htlc_id: u64,
        incoming_packet_shared_secret: [u8; 32],
+
+       // This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
+       // channel with a preimage provided by the forward channel.
+       outpoint: OutPoint,
 }
 
 struct ClaimableHTLC {
@@ -465,6 +475,7 @@ const CHECK_CLTV_EXPIRY_SANITY: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_P
 const CHECK_CLTV_EXPIRY_SANITY_2: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2*CLTV_CLAIM_BUFFER;
 
 /// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels
+#[derive(Clone)]
 pub struct ChannelDetails {
        /// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
        /// thereafter this is the txid of the funding transaction xor the funding transaction output).
@@ -1554,9 +1565,11 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                                        failed_forwards.reserve(pending_forwards.len());
                                                        for forward_info in pending_forwards.drain(..) {
                                                                match forward_info {
-                                                                       HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
+                                                                       HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info,
+                                                                                                  prev_funding_outpoint } => {
                                                                                let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
                                                                                        short_channel_id: prev_short_channel_id,
+                                                                                       outpoint: prev_funding_outpoint,
                                                                                        htlc_id: prev_htlc_id,
                                                                                        incoming_packet_shared_secret: forward_info.incoming_shared_secret,
                                                                                });
@@ -1583,10 +1596,12 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                                                HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
                                                                                routing: PendingHTLCRouting::Forward {
                                                                                        onion_packet, ..
-                                                                               }, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value }, } => {
+                                                                               }, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value },
+                                                                               prev_funding_outpoint } => {
                                                                        log_trace!(self.logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", log_bytes!(payment_hash.0), prev_short_channel_id, short_chan_id);
                                                                        let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
                                                                                short_channel_id: prev_short_channel_id,
+                                                                               outpoint: prev_funding_outpoint,
                                                                                htlc_id: prev_htlc_id,
                                                                                incoming_packet_shared_secret: incoming_shared_secret,
                                                                        });
@@ -1701,9 +1716,11 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                                match forward_info {
                                                        HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
                                                                        routing: PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry },
-                                                                       incoming_shared_secret, payment_hash, amt_to_forward, .. }, } => {
+                                                                       incoming_shared_secret, payment_hash, amt_to_forward, .. },
+                                                                       prev_funding_outpoint } => {
                                                                let prev_hop = HTLCPreviousHopData {
                                                                        short_channel_id: prev_short_channel_id,
+                                                                       outpoint: prev_funding_outpoint,
                                                                        htlc_id: prev_htlc_id,
                                                                        incoming_packet_shared_secret: incoming_shared_secret,
                                                                };
@@ -1738,6 +1755,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                                                                        );
                                                                                        failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData {
                                                                                                        short_channel_id: htlc.prev_hop.short_channel_id,
+                                                                                                       outpoint: prev_funding_outpoint,
                                                                                                        htlc_id: htlc.prev_hop.htlc_id,
                                                                                                        incoming_packet_shared_secret: htlc.prev_hop.incoming_packet_shared_secret,
                                                                                                }), payment_hash,
@@ -1940,7 +1958,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                        }
                                }
                        },
-                       HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret }) => {
+                       HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret, .. }) => {
                                let err_packet = match onion_error {
                                        HTLCFailReason::Reason { failure_code, data } => {
                                                log_trace!(self.logger, "Failing HTLC with payment_hash {} backwards from us with code {}", log_bytes!(payment_hash.0), failure_code);
@@ -2135,12 +2153,23 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                });
                        },
                        HTLCSource::PreviousHopData(hop_data) => {
+                               let prev_outpoint = hop_data.outpoint;
                                if let Err((counterparty_node_id, err)) = match self.claim_funds_from_hop(&mut channel_state_lock, hop_data, payment_preimage) {
                                        Ok(()) => Ok(()),
                                        Err(None) => {
-                                               // TODO: There is probably a channel monitor somewhere that needs to
-                                               // learn the preimage as the channel already hit the chain and that's
-                                               // why it's missing.
+                                               let preimage_update = ChannelMonitorUpdate {
+                                                       update_id: CLOSED_CHANNEL_UPDATE_ID,
+                                                       updates: vec![ChannelMonitorUpdateStep::PaymentPreimage {
+                                                               payment_preimage: payment_preimage.clone(),
+                                                       }],
+                                               };
+                                               // We update the ChannelMonitor on the backward link, after
+                                               // receiving an offchain preimage event from the forward link (the
+                                               // event being update_fulfill_htlc).
+                                               if let Err(e) = self.chain_monitor.update_channel(prev_outpoint, preimage_update) {
+                                                       log_error!(self.logger, "Critical error: failed to update channel monitor with preimage {:?}: {:?}",
+                                                                  payment_preimage, e);
+                                               }
                                                Ok(())
                                        },
                                        Err(Some(res)) => Err(res),
@@ -2201,7 +2230,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
 
                        let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe, funding_locked) = channel.monitor_updating_restored(&self.logger);
                        if !pending_forwards.is_empty() {
-                               htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), pending_forwards));
+                               htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), funding_txo.clone(), pending_forwards));
                        }
                        htlc_failures.append(&mut pending_failures);
 
@@ -2334,7 +2363,12 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                        // channel, not the temporary_channel_id. This is compatible with ourselves, but the
                                        // spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for
                                        // any messages referencing a previously-closed channel anyway.
-                                       return Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id, chan.force_shutdown(true), None));
+                                       // We do not do a force-close here as that would generate a monitor update for
+                                       // a monitor that we didn't manage to store (and that we don't care about - we
+                                       // don't respond with the funding_signed so the channel can never go on chain).
+                                       let (_funding_txo_option, _monitor_update, failed_htlcs) = chan.force_shutdown(true);
+                                       assert!(failed_htlcs.is_empty());
+                                       return Err(MsgHandleErrInternal::send_err_msg_no_close("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id));
                                },
                                ChannelMonitorUpdateErr::TemporaryFailure => {
                                        // There's no problem signing a counterparty's funding transaction if our monitor
@@ -2685,8 +2719,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
        }
 
        #[inline]
-       fn forward_htlcs(&self, per_source_pending_forwards: &mut [(u64, Vec<(PendingHTLCInfo, u64)>)]) {
-               for &mut (prev_short_channel_id, ref mut pending_forwards) in per_source_pending_forwards {
+       fn forward_htlcs(&self, per_source_pending_forwards: &mut [(u64, OutPoint, Vec<(PendingHTLCInfo, u64)>)]) {
+               for &mut (prev_short_channel_id, prev_funding_outpoint, ref mut pending_forwards) in per_source_pending_forwards {
                        let mut forward_event = None;
                        if !pending_forwards.is_empty() {
                                let mut channel_state = self.channel_state.lock().unwrap();
@@ -2699,10 +2733,12 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                                        PendingHTLCRouting::Receive { .. } => 0,
                                        }) {
                                                hash_map::Entry::Occupied(mut entry) => {
-                                                       entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info });
+                                                       entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_funding_outpoint,
+                                                                                                       prev_htlc_id, forward_info });
                                                },
                                                hash_map::Entry::Vacant(entry) => {
-                                                       entry.insert(vec!(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info }));
+                                                       entry.insert(vec!(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_funding_outpoint,
+                                                                                                    prev_htlc_id, forward_info }));
                                                }
                                        }
                                }
@@ -2755,18 +2791,18 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                                        msg,
                                                });
                                        }
-                                       break Ok((pending_forwards, pending_failures, chan.get().get_short_channel_id().expect("RAA should only work on a short-id-available channel")))
+                                       break Ok((pending_forwards, pending_failures, chan.get().get_short_channel_id().expect("RAA should only work on a short-id-available channel"), chan.get().get_funding_txo().unwrap()))
                                },
                                hash_map::Entry::Vacant(_) => break Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
                        }
                };
                self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id);
                match res {
-                       Ok((pending_forwards, mut pending_failures, short_channel_id)) => {
+                       Ok((pending_forwards, mut pending_failures, short_channel_id, channel_outpoint)) => {
                                for failure in pending_failures.drain(..) {
                                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), failure.0, &failure.1, failure.2);
                                }
-                               self.forward_htlcs(&mut [(short_channel_id, pending_forwards)]);
+                               self.forward_htlcs(&mut [(short_channel_id, channel_outpoint, pending_forwards)]);
                                Ok(())
                        },
                        Err(e) => Err(e)
@@ -3543,6 +3579,7 @@ impl Readable for PendingHTLCStatus {
 
 impl_writeable!(HTLCPreviousHopData, 0, {
        short_channel_id,
+       outpoint,
        htlc_id,
        incoming_packet_shared_secret
 });
@@ -3619,9 +3656,10 @@ impl Readable for HTLCFailReason {
 impl Writeable for HTLCForwardInfo {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
                match self {
-                       &HTLCForwardInfo::AddHTLC { ref prev_short_channel_id, ref prev_htlc_id, ref forward_info } => {
+                       &HTLCForwardInfo::AddHTLC { ref prev_short_channel_id, ref prev_funding_outpoint, ref prev_htlc_id, ref forward_info } => {
                                0u8.write(writer)?;
                                prev_short_channel_id.write(writer)?;
+                               prev_funding_outpoint.write(writer)?;
                                prev_htlc_id.write(writer)?;
                                forward_info.write(writer)?;
                        },
@@ -3640,6 +3678,7 @@ impl Readable for HTLCForwardInfo {
                match <u8 as Readable>::read(reader)? {
                        0 => Ok(HTLCForwardInfo::AddHTLC {
                                prev_short_channel_id: Readable::read(reader)?,
+                               prev_funding_outpoint: Readable::read(reader)?,
                                prev_htlc_id: Readable::read(reader)?,
                                forward_info: Readable::read(reader)?,
                        }),
index bc8351e4da09e333b5bcc481d8a94e079187753e..8ff3d4eacf85c3972d7dd322747570b9c66779fc 100644 (file)
@@ -487,7 +487,11 @@ pub fn create_announced_chan_between_nodes<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'
 
 pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, channel_value: u64, push_msat: u64, a_flags: InitFeatures, b_flags: InitFeatures) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
        let chan_announcement = create_chan_between_nodes_with_value(&nodes[a], &nodes[b], channel_value, push_msat, a_flags, b_flags);
+       update_nodes_with_chan_announce(nodes, a, b, &chan_announcement.0, &chan_announcement.1, &chan_announcement.2);
+       (chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
+}
 
+pub fn update_nodes_with_chan_announce<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, ann: &msgs::ChannelAnnouncement, upd_1: &msgs::ChannelUpdate, upd_2: &msgs::ChannelUpdate) {
        nodes[a].node.broadcast_node_announcement([0, 0, 0], [0; 32], Vec::new());
        let a_events = nodes[a].node.get_and_clear_pending_msg_events();
        assert_eq!(a_events.len(), 1);
@@ -509,13 +513,12 @@ pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a
        };
 
        for node in nodes {
-               assert!(node.net_graph_msg_handler.handle_channel_announcement(&chan_announcement.0).unwrap());
-               node.net_graph_msg_handler.handle_channel_update(&chan_announcement.1).unwrap();
-               node.net_graph_msg_handler.handle_channel_update(&chan_announcement.2).unwrap();
+               assert!(node.net_graph_msg_handler.handle_channel_announcement(ann).unwrap());
+               node.net_graph_msg_handler.handle_channel_update(upd_1).unwrap();
+               node.net_graph_msg_handler.handle_channel_update(upd_2).unwrap();
                node.net_graph_msg_handler.handle_node_announcement(&a_node_announcement).unwrap();
                node.net_graph_msg_handler.handle_node_announcement(&b_node_announcement).unwrap();
        }
-       (chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
 }
 
 macro_rules! check_spends {
index a2e12504031780718736fd9086f57a656da826b3..85dae76987dc669424486e2a5d0f03387d469dcf 100644 (file)
@@ -3523,7 +3523,7 @@ fn test_force_close_fail_back() {
        {
                let mut monitors = nodes[2].chain_monitor.chain_monitor.monitors.lock().unwrap();
                monitors.get_mut(&OutPoint{ txid: Txid::from_slice(&payment_event.commitment_msg.channel_id[..]).unwrap(), index: 0 }).unwrap()
-                       .provide_payment_preimage(&our_payment_hash, &our_payment_preimage);
+                       .provide_payment_preimage(&our_payment_hash, &our_payment_preimage, &node_cfgs[2].tx_broadcaster, &node_cfgs[2].fee_estimator, &&logger);
        }
        connect_block(&nodes[2], &block, 1);
        let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap();
@@ -8457,6 +8457,43 @@ fn test_concurrent_monitor_claim() {
        }
 }
 
+#[test]
+fn test_pre_lockin_no_chan_closed_update() {
+       // Test that if a peer closes a channel in response to a funding_created message we don't
+       // generate a channel update (as the channel cannot appear on chain without a funding_signed
+       // message).
+       //
+       // Doing so would imply a channel monitor update before the initial channel monitor
+       // registration, violating our API guarantees.
+       //
+       // Previously, full_stack_target managed to hit this case by opening then closing a channel,
+       // then opening a second channel with the same funding output as the first (which is not
+       // rejected because the first channel does not exist in the ChannelManager) and closing it
+       // before receiving funding_signed.
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       // Create an initial channel
+       nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
+       let mut open_chan_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_msg);
+       let accept_chan_msg = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_chan_msg);
+
+       // Move the first channel through the funding flow...
+       let (temporary_channel_id, _tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42);
+
+       nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_output);
+       check_added_monitors!(nodes[0], 0);
+
+       let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
+       let channel_id = ::chain::transaction::OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index }.to_channel_id();
+       nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage { channel_id, data: "Hi".to_owned() });
+       assert!(nodes[0].chain_monitor.added_monitors.lock().unwrap().is_empty());
+}
+
 #[test]
 fn test_htlc_no_detection() {
        // This test is a mutation to underscore the detection logic bug we had
@@ -8503,3 +8540,327 @@ fn test_htlc_no_detection() {
         connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1, 201, true, header_201.block_hash());
         expect_payment_failed!(nodes[0], our_payment_hash, true);
 }
+
+fn do_test_onchain_htlc_settlement_after_close(broadcast_alice: bool, go_onchain_before_fulfill: bool) {
+       // If we route an HTLC, then learn the HTLC's preimage after the upstream channel has been
+       // force-closed, we must claim that HTLC on-chain. (Given an HTLC forwarded from Alice --> Bob -->
+       // Carol, Alice would be the upstream node, and Carol the downstream.)
+       //
+       // Steps of the test:
+       // 1) Alice sends a HTLC to Carol through Bob.
+       // 2) Carol doesn't settle the HTLC.
+       // 3) If broadcast_alice is true, Alice force-closes her channel with Bob. Else Bob force closes.
+       // Steps 4 and 5 may be reordered depending on go_onchain_before_fulfill.
+       // 4) Bob sees the Alice's commitment on his chain or vice versa. An offered output is present
+       //    but can't be claimed as Bob doesn't have yet knowledge of the preimage.
+       // 5) Carol release the preimage to Bob off-chain.
+       // 6) Bob claims the offered output on the broadcasted commitment.
+       let chanmon_cfgs = create_chanmon_cfgs(3);
+       let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
+       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       // Create some initial channels
+       let chan_ab = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known());
+       create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 10001, InitFeatures::known(), InitFeatures::known());
+
+       // Steps (1) and (2):
+       // Send an HTLC Alice --> Bob --> Carol, but Carol doesn't settle the HTLC back.
+       let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), 3_000_000);
+
+       // Check that Alice's commitment transaction now contains an output for this HTLC.
+       let alice_txn = get_local_commitment_txn!(nodes[0], chan_ab.2);
+       check_spends!(alice_txn[0], chan_ab.3);
+       assert_eq!(alice_txn[0].output.len(), 2);
+       check_spends!(alice_txn[1], alice_txn[0]); // 2nd transaction is a non-final HTLC-timeout
+       assert_eq!(alice_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+       assert_eq!(alice_txn.len(), 2);
+
+       // Steps (3) and (4):
+       // If `go_onchain_before_fufill`, broadcast the relevant commitment transaction and check that Bob
+       // responds by (1) broadcasting a channel update and (2) adding a new ChannelMonitor.
+       let mut force_closing_node = 0; // Alice force-closes
+       if !broadcast_alice { force_closing_node = 1; } // Bob force-closes
+       nodes[force_closing_node].node.force_close_channel(&chan_ab.2);
+       check_closed_broadcast!(nodes[force_closing_node], false);
+       check_added_monitors!(nodes[force_closing_node], 1);
+       if go_onchain_before_fulfill {
+               let txn_to_broadcast = match broadcast_alice {
+                       true => alice_txn.clone(),
+                       false => get_local_commitment_txn!(nodes[1], chan_ab.2)
+               };
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
+               connect_block(&nodes[1], &Block { header, txdata: vec![txn_to_broadcast[0].clone()]}, 1);
+               let mut bob_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+               if broadcast_alice {
+                       check_closed_broadcast!(nodes[1], false);
+                       check_added_monitors!(nodes[1], 1);
+               }
+               assert_eq!(bob_txn.len(), 1);
+               check_spends!(bob_txn[0], chan_ab.3);
+       }
+
+       // Step (5):
+       // Carol then claims the funds and sends an update_fulfill message to Bob, and they go through the
+       // process of removing the HTLC from their commitment transactions.
+       assert!(nodes[2].node.claim_funds(payment_preimage, &None, 3_000_000));
+       check_added_monitors!(nodes[2], 1);
+       let carol_updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
+       assert!(carol_updates.update_add_htlcs.is_empty());
+       assert!(carol_updates.update_fail_htlcs.is_empty());
+       assert!(carol_updates.update_fail_malformed_htlcs.is_empty());
+       assert!(carol_updates.update_fee.is_none());
+       assert_eq!(carol_updates.update_fulfill_htlcs.len(), 1);
+
+       nodes[1].node.handle_update_fulfill_htlc(&nodes[2].node.get_our_node_id(), &carol_updates.update_fulfill_htlcs[0]);
+       // If Alice broadcasted but Bob doesn't know yet, here he prepares to tell her about the preimage.
+       if !go_onchain_before_fulfill && broadcast_alice {
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::UpdateHTLCs { ref node_id, .. } => {
+                               assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+       }
+       nodes[1].node.handle_commitment_signed(&nodes[2].node.get_our_node_id(), &carol_updates.commitment_signed);
+       // One monitor update for the preimage to update the Bob<->Alice channel, one monitor update
+       // Carol<->Bob's updated commitment transaction info.
+       check_added_monitors!(nodes[1], 2);
+
+       let events = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), 2);
+       let bob_revocation = match events[0] {
+               MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
+                       assert_eq!(*node_id, nodes[2].node.get_our_node_id());
+                       (*msg).clone()
+               },
+               _ => panic!("Unexpected event"),
+       };
+       let bob_updates = match events[1] {
+               MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
+                       assert_eq!(*node_id, nodes[2].node.get_our_node_id());
+                       (*updates).clone()
+               },
+               _ => panic!("Unexpected event"),
+       };
+
+       nodes[2].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bob_revocation);
+       check_added_monitors!(nodes[2], 1);
+       nodes[2].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bob_updates.commitment_signed);
+       check_added_monitors!(nodes[2], 1);
+
+       let events = nodes[2].node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), 1);
+       let carol_revocation = match events[0] {
+               MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
+                       assert_eq!(*node_id, nodes[1].node.get_our_node_id());
+                       (*msg).clone()
+               },
+               _ => panic!("Unexpected event"),
+       };
+       nodes[1].node.handle_revoke_and_ack(&nodes[2].node.get_our_node_id(), &carol_revocation);
+       check_added_monitors!(nodes[1], 1);
+
+       // If this test requires the force-closed channel to not be on-chain until after the fulfill,
+       // here's where we put said channel's commitment tx on-chain.
+       let mut txn_to_broadcast = alice_txn.clone();
+       if !broadcast_alice { txn_to_broadcast = get_local_commitment_txn!(nodes[1], chan_ab.2); }
+       if !go_onchain_before_fulfill {
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
+               connect_block(&nodes[1], &Block { header, txdata: vec![txn_to_broadcast[0].clone()]}, 1);
+               // If Bob was the one to force-close, he will have already passed these checks earlier.
+               if broadcast_alice {
+                       check_closed_broadcast!(nodes[1], false);
+                       check_added_monitors!(nodes[1], 1);
+               }
+               let mut bob_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+               if broadcast_alice {
+                       // In `connect_block()`, the ChainMonitor and ChannelManager are separately notified about a
+                       // new block being connected. The ChannelManager being notified triggers a monitor update,
+                       // which triggers broadcasting our commitment tx and an HTLC-claiming tx. The ChainMonitor
+                       // being notified triggers the HTLC-claiming tx redundantly, resulting in 3 total txs being
+                       // broadcasted.
+                       assert_eq!(bob_txn.len(), 3);
+                       check_spends!(bob_txn[1], chan_ab.3);
+               } else {
+                       assert_eq!(bob_txn.len(), 2);
+                       check_spends!(bob_txn[0], chan_ab.3);
+               }
+       }
+
+       // Step (6):
+       // Finally, check that Bob broadcasted a preimage-claiming transaction for the HTLC output on the
+       // broadcasted commitment transaction.
+       {
+               let bob_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
+               if go_onchain_before_fulfill {
+                       // Bob should now have an extra broadcasted tx, for the preimage-claiming transaction.
+                       assert_eq!(bob_txn.len(), 2);
+               }
+               let script_weight = match broadcast_alice {
+                       true => OFFERED_HTLC_SCRIPT_WEIGHT,
+                       false => ACCEPTED_HTLC_SCRIPT_WEIGHT
+               };
+               // If Alice force-closed and Bob didn't receive her commitment transaction until after he
+               // received Carol's fulfill, he broadcasts the HTLC-output-claiming transaction first. Else if
+               // Bob force closed or if he found out about Alice's commitment tx before receiving Carol's
+               // fulfill, then he broadcasts the HTLC-output-claiming transaction second.
+               if broadcast_alice && !go_onchain_before_fulfill {
+                       check_spends!(bob_txn[0], txn_to_broadcast[0]);
+                       assert_eq!(bob_txn[0].input[0].witness.last().unwrap().len(), script_weight);
+               } else {
+                       check_spends!(bob_txn[1], txn_to_broadcast[0]);
+                       assert_eq!(bob_txn[1].input[0].witness.last().unwrap().len(), script_weight);
+               }
+       }
+}
+
+#[test]
+fn test_onchain_htlc_settlement_after_close() {
+       do_test_onchain_htlc_settlement_after_close(true, true);
+       do_test_onchain_htlc_settlement_after_close(false, true); // Technically redundant, but may as well
+       do_test_onchain_htlc_settlement_after_close(true, false);
+       do_test_onchain_htlc_settlement_after_close(false, false);
+}
+
+#[test]
+fn test_duplicate_chan_id() {
+       // Test that if a given peer tries to open a channel with the same channel_id as one that is
+       // already open we reject it and keep the old channel.
+       //
+       // Previously, full_stack_target managed to figure out that if you tried to open two channels
+       // with the same funding output (ie post-funding channel_id), we'd create a monitor update for
+       // the existing channel when we detect the duplicate new channel, screwing up our monitor
+       // updating logic for the existing channel.
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       // Create an initial channel
+       nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
+       let mut open_chan_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_msg);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+
+       // Try to create a second channel with the same temporary_channel_id as the first and check
+       // that it is rejected.
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_msg);
+       {
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
+                               // Technically, at this point, nodes[1] would be justified in thinking both the
+                               // first (valid) and second (invalid) channels are closed, given they both have
+                               // the same non-temporary channel_id. However, currently we do not, so we just
+                               // move forward with it.
+                               assert_eq!(msg.channel_id, open_chan_msg.temporary_channel_id);
+                               assert_eq!(node_id, nodes[0].node.get_our_node_id());
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
+       // Move the first channel through the funding flow...
+       let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42);
+
+       nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_output);
+       check_added_monitors!(nodes[0], 0);
+
+       let mut funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
+       {
+               let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
+               assert_eq!(added_monitors.len(), 1);
+               assert_eq!(added_monitors[0].0, funding_output);
+               added_monitors.clear();
+       }
+       let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+
+       let funding_outpoint = ::chain::transaction::OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index };
+       let channel_id = funding_outpoint.to_channel_id();
+
+       // Now we have the first channel past funding_created (ie it has a txid-based channel_id, not a
+       // temporary one).
+
+       // First try to open a second channel with a temporary channel id equal to the txid-based one.
+       // Technically this is allowed by the spec, but we don't support it and there's little reason
+       // to. Still, it shouldn't cause any other issues.
+       open_chan_msg.temporary_channel_id = channel_id;
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_msg);
+       {
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
+                               // Technically, at this point, nodes[1] would be justified in thinking both
+                               // channels are closed, but currently we do not, so we just move forward with it.
+                               assert_eq!(msg.channel_id, open_chan_msg.temporary_channel_id);
+                               assert_eq!(node_id, nodes[0].node.get_our_node_id());
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
+       // Now try to create a second channel which has a duplicate funding output.
+       nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
+       let open_chan_2_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_2_msg);
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+       create_funding_transaction(&nodes[0], 100000, 42); // Get and check the FundingGenerationReady event
+
+       let funding_created = {
+               let mut a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
+               let mut as_chan = a_channel_lock.by_id.get_mut(&open_chan_2_msg.temporary_channel_id).unwrap();
+               let logger = test_utils::TestLogger::new();
+               as_chan.get_outbound_funding_created(funding_outpoint, &&logger).unwrap()
+       };
+       check_added_monitors!(nodes[0], 0);
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
+       // At this point we'll try to add a duplicate channel monitor, which will be rejected, but
+       // still needs to be cleared here.
+       check_added_monitors!(nodes[1], 1);
+
+       // ...still, nodes[1] will reject the duplicate channel.
+       {
+               let events = nodes[1].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
+                               // Technically, at this point, nodes[1] would be justified in thinking both
+                               // channels are closed, but currently we do not, so we just move forward with it.
+                               assert_eq!(msg.channel_id, channel_id);
+                               assert_eq!(node_id, nodes[0].node.get_our_node_id());
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
+       // finally, finish creating the original channel and send a payment over it to make sure
+       // everything is functional.
+       nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed_msg);
+       {
+               let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap();
+               assert_eq!(added_monitors.len(), 1);
+               assert_eq!(added_monitors[0].0, funding_output);
+               added_monitors.clear();
+       }
+
+       let events_4 = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events_4.len(), 1);
+       match events_4[0] {
+               Event::FundingBroadcastSafe { ref funding_txo, user_channel_id } => {
+                       assert_eq!(user_channel_id, 42);
+                       assert_eq!(*funding_txo, funding_output);
+               },
+               _ => panic!("Unexpected event"),
+       };
+
+       let (funding_locked, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
+       let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked);
+       update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update);
+       send_payment(&nodes[0], &[&nodes[1]], 8000000, 8_000_000);
+}
index 16ba08629fe66bab2cfe0f2d4b2b036e981d4234..f57cf0fd1fb9304fac06f34fad5164e6e8a1dfe4 100644 (file)
@@ -64,6 +64,7 @@ pub enum DecodeError {
 }
 
 /// An init message to be sent or received from a peer
+#[derive(Clone)]
 pub struct Init {
        #[cfg(not(feature = "fuzztarget"))]
        pub(crate) features: InitFeatures,
@@ -84,6 +85,7 @@ pub struct ErrorMessage {
 }
 
 /// A ping message to be sent or received from a peer
+#[derive(Clone)]
 pub struct Ping {
        /// The desired response length
        pub ponglen: u16,
@@ -93,6 +95,7 @@ pub struct Ping {
 }
 
 /// A pong message to be sent or received from a peer
+#[derive(Clone)]
 pub struct Pong {
        /// The pong packet size.
        /// This field is not sent on the wire. byteslen zeros are sent.
index 2f1565631ea9fe9ce94244dd3bab6ab71f480a75..3484d8983f60fc0e9367993b5b5de3b4979dc8ff 100644 (file)
@@ -282,6 +282,8 @@ pub struct OnchainTxHandler<ChanSigner: ChannelKeys> {
 
        onchain_events_waiting_threshold_conf: HashMap<u32, Vec<OnchainEvent>>,
 
+       latest_height: u32,
+
        secp_ctx: Secp256k1<secp256k1::All>,
 }
 
@@ -328,6 +330,7 @@ impl<ChanSigner: ChannelKeys + Writeable> OnchainTxHandler<ChanSigner> {
                                }
                        }
                }
+               self.latest_height.write(writer)?;
                Ok(())
        }
 }
@@ -387,6 +390,7 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for OnchainTxHandler<ChanSigne
                        }
                        onchain_events_waiting_threshold_conf.insert(height_target, events);
                }
+               let latest_height = Readable::read(reader)?;
 
                Ok(OnchainTxHandler {
                        destination_script,
@@ -399,6 +403,7 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for OnchainTxHandler<ChanSigne
                        claimable_outpoints,
                        pending_claim_requests,
                        onchain_events_waiting_threshold_conf,
+                       latest_height,
                        secp_ctx: Secp256k1::new(),
                })
        }
@@ -420,6 +425,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
                        pending_claim_requests: HashMap::new(),
                        claimable_outpoints: HashMap::new(),
                        onchain_events_waiting_threshold_conf: HashMap::new(),
+                       latest_height: 0,
 
                        secp_ctx: Secp256k1::new(),
                }
@@ -471,7 +477,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
 
        /// Lightning security model (i.e being able to redeem/timeout HTLC or penalize coutnerparty onchain) lays on the assumption of claim transactions getting confirmed before timelock expiration
        /// (CSV or CLTV following cases). In case of high-fee spikes, claim tx may stuck in the mempool, so you need to bump its feerate quickly using Replace-By-Fee or Child-Pay-For-Parent.
-       fn generate_claim_tx<F: Deref, L: Deref>(&mut self, height: u32, cached_claim_datas: &ClaimTxBumpMaterial, fee_estimator: F, logger: L) -> Option<(Option<u32>, u32, Transaction)>
+       fn generate_claim_tx<F: Deref, L: Deref>(&mut self, height: u32, cached_claim_datas: &ClaimTxBumpMaterial, fee_estimator: &F, logger: &L) -> Option<(Option<u32>, u32, Transaction)>
                where F::Target: FeeEstimator,
                                        L::Target: Logger,
        {
@@ -657,12 +663,20 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
                None
        }
 
-       pub(crate) fn block_connected<B: Deref, F: Deref, L: Deref>(&mut self, txn_matched: &[&Transaction], claimable_outpoints: Vec<ClaimRequest>, height: u32, broadcaster: B, fee_estimator: F, logger: L)
+       /// Upon channelmonitor.block_connected(..) or upon provision of a preimage on the forward link
+       /// for this channel, provide new relevant on-chain transactions and/or new claim requests.
+       /// Formerly this was named `block_connected`, but it is now also used for claiming an HTLC output
+       /// if we receive a preimage after force-close.
+       pub(crate) fn update_claims_view<B: Deref, F: Deref, L: Deref>(&mut self, txn_matched: &[&Transaction], claimable_outpoints: Vec<ClaimRequest>, latest_height: Option<u32>, broadcaster: &B, fee_estimator: &F, logger: &L)
                where B::Target: BroadcasterInterface,
                      F::Target: FeeEstimator,
                                        L::Target: Logger,
        {
-               log_trace!(logger, "Block at height {} connected with {} claim requests", height, claimable_outpoints.len());
+               let height = match latest_height {
+                       Some(h) => h,
+                       None => self.latest_height,
+               };
+               log_trace!(logger, "Updating claims view at height {} with {} matched transactions and {} claim requests", height, txn_matched.len(), claimable_outpoints.len());
                let mut new_claims = Vec::new();
                let mut aggregated_claim = HashMap::new();
                let mut aggregated_soonest = ::std::u32::MAX;
@@ -855,7 +869,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
                        }
                }
                for (_, claim_material) in bump_candidates.iter_mut() {
-                       if let Some((new_timer, new_feerate, bump_tx)) = self.generate_claim_tx(height, &claim_material, &*fee_estimator, &*logger) {
+                       if let Some((new_timer, new_feerate, bump_tx)) = self.generate_claim_tx(height, &claim_material, &&*fee_estimator, &&*logger) {
                                claim_material.height_timer = new_timer;
                                claim_material.feerate_previous = new_feerate;
                                broadcaster.broadcast_transaction(&bump_tx);
index 526d26b56bb01c152858b4b92e14ba5678d0c7c4..490b6b4048cbd33a7ba60e8b578b6dddbfcd4e17 100644 (file)
@@ -113,6 +113,7 @@ impl Readable for Route {
 }
 
 /// A channel descriptor which provides a last-hop route to get_route
+#[derive(Clone)]
 pub struct RouteHint {
        /// The node_id of the non-target end of the route
        pub src_node_id: PublicKey,
index 60191b886d59222bf7b2310e2f80264942cce70c..3eeacdc732cb12969f0cddd69aa329745dce5297 100644 (file)
@@ -31,7 +31,7 @@ use std::time::Duration;
 /// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
 /// them directly as they don't round-trip exactly (for example FundingGenerationReady is never
 /// written as it makes no sense to respond to it after reconnecting to peers).
-#[derive(Debug)]
+#[derive(Clone, Debug)]
 pub enum Event {
        /// Used to indicate that the client should generate a funding transaction with the given
        /// parameters and then call ChannelManager::funding_transaction_generated.