From: Matt Corallo <649246+TheBlueMatt@users.noreply.github.com> Date: Wed, 2 Jun 2021 03:50:57 +0000 (+0000) Subject: Merge pull request #24 from TheBlueMatt/main X-Git-Tag: v0.0.98~5 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-c-bindings;a=commitdiff_plain;h=6658ad877ed253301df2c729b1c6a2a859515777;hp=7e6274489182ebb64202f790e462a9d464d75de2 Merge pull request #24 from TheBlueMatt/main Update Bindings for latest Upstream LDK --- diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 7d26edc..7f95ef8 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -180,7 +180,7 @@ eprintln!("{}", trait_path); // *** Per-Type Printing Logic *** // ******************************* -macro_rules! walk_supertraits { ($t: expr, $types: expr, ($( $pat: pat => $e: expr),*) ) => { { +macro_rules! walk_supertraits { ($t: expr, $types: expr, ($( $($pat: pat)|* => $e: expr),*) ) => { { if $t.colon_token.is_some() { for st in $t.supertraits.iter() { match st { @@ -194,14 +194,14 @@ macro_rules! walk_supertraits { ($t: expr, $types: expr, ($( $pat: pat => $e: ex if let Some(types) = types_opt { if let Some(path) = types.maybe_resolve_path(&supertrait.path, None) { match (&path as &str, &supertrait.path.segments.iter().last().unwrap().ident) { - $( $pat => $e, )* + $( $($pat)|* => $e, )* } continue; } } if let Some(ident) = supertrait.path.get_ident() { match (&format!("{}", ident) as &str, &ident) { - $( $pat => $e, )* + $( $($pat)|* => $e, )* } } else if types_opt.is_some() { panic!("Supertrait unresolvable and not single-ident"); @@ -221,8 +221,10 @@ macro_rules! walk_supertraits { ($t: expr, $types: expr, ($( $pat: pat => $e: ex /// a concrete Deref to the Rust trait. fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, types: &mut TypeResolver<'b, 'a>, extra_headers: &mut File, cpp_headers: &mut File) { let trait_name = format!("{}", t.ident); + let implementable; match export_status(&t.attrs) { - ExportStatus::Export => {}, + ExportStatus::Export => { implementable = true; } + ExportStatus::NotImplementable => { implementable = false; }, ExportStatus::NoExport|ExportStatus::TestOnly => return, } writeln_docs(w, &t.attrs, ""); @@ -247,6 +249,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty }, ExportStatus::Export => {}, ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } if m.default.is_some() { unimplemented!(); } @@ -311,13 +314,13 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty writeln!(w, "\tpub clone: Option *mut c_void>,").unwrap(); generated_fields.push(("clone".to_owned(), true)); }, - ("std::cmp::Eq", _) => { + ("std::cmp::Eq", _)|("core::cmp::Eq", _) => { writeln!(w, "\t/// Checks if two objects are equal given this object's this_arg pointer and another object.").unwrap(); writeln!(w, "\tpub eq: extern \"C\" fn (this_arg: *const c_void, other_arg: &{}) -> bool,", trait_name).unwrap(); writeln!(extra_headers, "typedef struct LDK{} LDK{};", trait_name, trait_name).unwrap(); generated_fields.push(("eq".to_owned(), true)); }, - ("std::hash::Hash", _) => { + ("std::hash::Hash", _)|("core::hash::Hash", _) => { writeln!(w, "\t/// Calculate a succinct non-cryptographic hash for an object given its this_arg pointer.").unwrap(); writeln!(w, "\t/// This is used, for example, for inclusion of this object in a hash map.").unwrap(); writeln!(w, "\tpub hash: extern \"C\" fn (this_arg: *const c_void) -> u64,").unwrap(); @@ -452,12 +455,12 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty walk_supertraits!(t, Some(&types), ( ("Send", _) => writeln!(w, "unsafe impl Send for {} {{}}", trait_name).unwrap(), ("Sync", _) => writeln!(w, "unsafe impl Sync for {} {{}}", trait_name).unwrap(), - ("std::cmp::Eq", _) => { + ("std::cmp::Eq", _)|("core::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) }}\n}}").unwrap(); }, - ("std::hash::Hash", _) => { + ("std::hash::Hash", _)|("core::hash::Hash", _) => { writeln!(w, "impl std::hash::Hash for {} {{", trait_name).unwrap(); writeln!(w, "\tfn hash(&self, hasher: &mut H) {{ hasher.write_u64((self.hash)(self.this_arg)) }}\n}}").unwrap(); }, @@ -505,15 +508,17 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty // Finally, implement the original Rust trait for the newly created mapped trait. writeln!(w, "\nuse {}::{} as rust{};", types.module_path, t.ident, trait_name).unwrap(); - write!(w, "impl rust{}", t.ident).unwrap(); - maybe_write_generics(w, &t.generics, types, false); - writeln!(w, " for {} {{", trait_name).unwrap(); - impl_trait_for_c!(t, "", types); - writeln!(w, "}}\n").unwrap(); - writeln!(w, "// We're essentially a pointer already, or at least a set of pointers, so allow us to be used").unwrap(); - writeln!(w, "// directly as a Deref trait in higher-level structs:").unwrap(); - writeln!(w, "impl std::ops::Deref for {} {{\n\ttype Target = Self;", trait_name).unwrap(); - writeln!(w, "\tfn deref(&self) -> &Self {{\n\t\tself\n\t}}\n}}").unwrap(); + if implementable { + write!(w, "impl rust{}", t.ident).unwrap(); + maybe_write_generics(w, &t.generics, types, false); + writeln!(w, " for {} {{", trait_name).unwrap(); + impl_trait_for_c!(t, "", types); + writeln!(w, "}}\n").unwrap(); + writeln!(w, "// We're essentially a pointer already, or at least a set of pointers, so allow us to be used").unwrap(); + writeln!(w, "// directly as a Deref trait in higher-level structs:").unwrap(); + writeln!(w, "impl std::ops::Deref for {} {{\n\ttype Target = Self;", trait_name).unwrap(); + writeln!(w, "\tfn deref(&self) -> &Self {{\n\t\tself\n\t}}\n}}").unwrap(); + } writeln!(w, "/// Calls the free function if one is set").unwrap(); writeln!(w, "#[no_mangle]\npub extern \"C\" fn {}_free(this_ptr: {}) {{ }}", trait_name, trait_name).unwrap(); @@ -597,6 +602,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct, all_fields_settable = false; continue }, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } if let Some(ident) = &field.ident { @@ -675,6 +681,7 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ match export_status(&i.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => return, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } if let syn::Type::Tuple(_) = &*i.self_ty { @@ -739,7 +746,7 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ let export = export_status(&trait_obj.attrs); match export { - ExportStatus::Export => {}, + ExportStatus::Export|ExportStatus::NotImplementable => {}, ExportStatus::NoExport|ExportStatus::TestOnly => return, } @@ -776,6 +783,7 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ continue; }, ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } let mut printed = false; @@ -843,6 +851,7 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ match export_status(&trait_method.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } if let syn::ReturnType::Type(_, _) = &$m.sig.output { @@ -940,6 +949,52 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ write!(w, "\t{} {{ inner: Box::into_raw(Box::new(Default::default())), is_owned: true }}\n", ident).unwrap(); write!(w, "}}\n").unwrap(); } else if path_matches_nongeneric(&trait_path.1, &["core", "cmp", "PartialEq"]) { + } else if path_matches_nongeneric(&trait_path.1, &["core", "cmp", "Eq"]) { + writeln!(w, "/// Checks if two {}s contain equal inner contents.", ident).unwrap(); + writeln!(w, "/// This ignores pointers and is_owned flags and looks at the values in fields.").unwrap(); + if types.c_type_has_inner_from_path(&resolved_path) { + writeln!(w, "/// Two objects with NULL inner values will be considered \"equal\" here.").unwrap(); + } + write!(w, "#[no_mangle]\npub extern \"C\" fn {}_eq(a: &{}, b: &{}) -> bool {{\n", ident, ident, ident).unwrap(); + if types.c_type_has_inner_from_path(&resolved_path) { + write!(w, "\tif a.inner == b.inner {{ return true; }}\n").unwrap(); + write!(w, "\tif a.inner.is_null() || b.inner.is_null() {{ return false; }}\n").unwrap(); + } + + let path = &p.path; + let ref_type: syn::Type = syn::parse_quote!(&#path); + assert!(!types.write_to_c_conversion_new_var(w, &format_ident!("a"), &*i.self_ty, Some(&gen_types), false), "We don't support new var conversions when comparing equality"); + + write!(w, "\tif ").unwrap(); + types.write_from_c_conversion_prefix(w, &ref_type, Some(&gen_types)); + write!(w, "a").unwrap(); + types.write_from_c_conversion_suffix(w, &ref_type, Some(&gen_types)); + write!(w, " == ").unwrap(); + types.write_from_c_conversion_prefix(w, &ref_type, Some(&gen_types)); + write!(w, "b").unwrap(); + types.write_from_c_conversion_suffix(w, &ref_type, Some(&gen_types)); + + writeln!(w, " {{ true }} else {{ false }}\n}}").unwrap(); + } else if path_matches_nongeneric(&trait_path.1, &["core", "hash", "Hash"]) { + writeln!(w, "/// Checks if two {}s contain equal inner contents.", ident).unwrap(); + write!(w, "#[no_mangle]\npub extern \"C\" fn {}_hash(o: &{}) -> u64 {{\n", ident, ident).unwrap(); + if types.c_type_has_inner_from_path(&resolved_path) { + write!(w, "\tif o.inner.is_null() {{ return 0; }}\n").unwrap(); + } + + let path = &p.path; + let ref_type: syn::Type = syn::parse_quote!(&#path); + assert!(!types.write_to_c_conversion_new_var(w, &format_ident!("a"), &*i.self_ty, Some(&gen_types), false), "We don't support new var conversions when comparing equality"); + + writeln!(w, "\t// Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core").unwrap(); + writeln!(w, "\t#[allow(deprecated)]").unwrap(); + writeln!(w, "\tlet mut hasher = core::hash::SipHasher::new();").unwrap(); + write!(w, "\tstd::hash::Hash::hash(").unwrap(); + types.write_from_c_conversion_prefix(w, &ref_type, Some(&gen_types)); + write!(w, "o").unwrap(); + types.write_from_c_conversion_suffix(w, &ref_type, Some(&gen_types)); + writeln!(w, ", &mut hasher);").unwrap(); + writeln!(w, "\tstd::hash::Hasher::finish(&hasher)\n}}").unwrap(); } else if (path_matches_nongeneric(&trait_path.1, &["core", "clone", "Clone"]) || path_matches_nongeneric(&trait_path.1, &["Clone"])) && types.c_type_has_inner_from_path(&resolved_path) { writeln!(w, "impl Clone for {} {{", ident).unwrap(); @@ -1006,6 +1061,7 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ match export_status(&m.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } if m.defaultness.is_some() { unimplemented!(); } writeln_docs(w, &m.attrs, ""); @@ -1128,6 +1184,7 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type match export_status(&e.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => return, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } if is_enum_opaque(e) { @@ -1328,6 +1385,7 @@ fn writeln_fn<'a, 'b, W: std::io::Write>(w: &mut W, f: &'a syn::ItemFn, types: & match export_status(&f.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => return, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } writeln_docs(w, &f.attrs, ""); @@ -1481,6 +1539,7 @@ fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &CrateTypes<'a> match export_status(&t.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } let mut process_alias = true; @@ -1552,6 +1611,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a match export_status(&s.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } let struct_path = format!("{}::{}", module, s.ident); crate_types.opaques.insert(struct_path, &s.ident); @@ -1560,7 +1620,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a syn::Item::Trait(t) => { if let syn::Visibility::Public(_) = t.vis { match export_status(&t.attrs) { - ExportStatus::Export => {}, + ExportStatus::Export|ExportStatus::NotImplementable => {}, ExportStatus::NoExport|ExportStatus::TestOnly => continue, } let trait_path = format!("{}::{}", module, t.ident); @@ -1578,6 +1638,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a match export_status(&t.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } let type_path = format!("{}::{}", module, t.ident); let mut process_alias = true; @@ -1612,6 +1673,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a match export_status(&e.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } let enum_path = format!("{}::{}", module, e.ident); crate_types.opaques.insert(enum_path, &e.ident); @@ -1622,6 +1684,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a match export_status(&e.attrs) { ExportStatus::Export => {}, ExportStatus::NoExport|ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } let enum_path = format!("{}::{}", module, e.ident); crate_types.mirrored_enums.insert(enum_path, &e); diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index a705ca2..26a0885 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -66,6 +66,11 @@ pub enum ExportStatus { Export, NoExport, TestOnly, + /// This is used only for traits to indicate that users should not be able to implement their + /// own version of a trait, but we should export Rust implementations of the trait (and the + /// trait itself). + /// Concretly, this means that we do not implement the Rust trait for the C trait struct. + NotImplementable, } /// Gets the ExportStatus of an object (struct, fn, etc) given its attributes. pub fn export_status(attrs: &[syn::Attribute]) -> ExportStatus { @@ -117,6 +122,8 @@ pub fn export_status(attrs: &[syn::Attribute]) -> ExportStatus { let line = format!("{}", lit); if line.contains("(C-not exported)") { return ExportStatus::NoExport; + } else if line.contains("(C-not implementable)") { + return ExportStatus::NotImplementable; } }, _ => unimplemented!(), @@ -138,6 +145,7 @@ pub fn is_enum_opaque(e: &syn::ItemEnum) -> bool { for field in fields.named.iter() { match export_status(&field.attrs) { ExportStatus::Export|ExportStatus::TestOnly => {}, + ExportStatus::NotImplementable => panic!("(C-not implementable) should only appear on traits!"), ExportStatus::NoExport => return true, } } @@ -145,6 +153,7 @@ pub fn is_enum_opaque(e: &syn::ItemEnum) -> bool { for field in fields.unnamed.iter() { match export_status(&field.attrs) { ExportStatus::Export|ExportStatus::TestOnly => {}, + ExportStatus::NotImplementable => panic!("(C-not implementable) should only appear on traits!"), ExportStatus::NoExport => return true, } } @@ -201,7 +210,7 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { if path == "Sized" { continue; } if non_lifetimes_processed { return false; } non_lifetimes_processed = true; - let new_ident = if path != "std::ops::Deref" { + let new_ident = if path != "std::ops::Deref" && path != "core::ops::Deref" { path = "crate::".to_string() + &path; Some(&trait_bound.path) } else { None }; @@ -226,7 +235,7 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { if p.path.leading_colon.is_some() { return false; } let mut p_iter = p.path.segments.iter(); if let Some(gen) = self.typed_generics.get_mut(&p_iter.next().unwrap().ident) { - if gen.0 != "std::ops::Deref" { return false; } + if gen.0 != "std::ops::Deref" && gen.0 != "core::ops::Deref" { return false; } if &format!("{}", p_iter.next().unwrap().ident) != "Target" { return false; } let mut non_lifetimes_processed = false; @@ -269,7 +278,7 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { // implement Deref for relevant types). We don't // bother to implement it for associated types, however, so we just // ignore such bounds. - let new_ident = if path != "std::ops::Deref" { + let new_ident = if path != "std::ops::Deref" && path != "core::ops::Deref" { path = "crate::".to_string() + &path; Some(&tr.path) } else { None }; @@ -479,6 +488,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr ExportStatus::Export => { declared.insert(s.ident.clone(), DeclType::StructImported); }, ExportStatus::NoExport => { declared.insert(s.ident.clone(), DeclType::StructIgnored); }, ExportStatus::TestOnly => continue, + ExportStatus::NotImplementable => panic!("(C-not implementable) should only appear on traits!"), } } }, @@ -499,13 +509,19 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr match export_status(&e.attrs) { ExportStatus::Export if is_enum_opaque(e) => { declared.insert(e.ident.clone(), DeclType::EnumIgnored); }, ExportStatus::Export => { declared.insert(e.ident.clone(), DeclType::MirroredEnum); }, + ExportStatus::NotImplementable => panic!("(C-not implementable) should only appear on traits!"), _ => continue, } } }, - syn::Item::Trait(t) if export_status(&t.attrs) == ExportStatus::Export => { - if let syn::Visibility::Public(_) = t.vis { - declared.insert(t.ident.clone(), DeclType::Trait(t)); + syn::Item::Trait(t) => { + match export_status(&t.attrs) { + ExportStatus::Export|ExportStatus::NotImplementable => { + if let syn::Visibility::Public(_) = t.vis { + declared.insert(t.ident.clone(), DeclType::Trait(t)); + } + }, + _ => continue, } }, syn::Item::Mod(m) => { @@ -842,9 +858,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[u8; 3]" if !is_ref => Some("crate::c_types::ThreeBytes"), // Used for RGB values "str" if is_ref => Some("crate::c_types::Str"), - "String" => Some("crate::c_types::Str"), + "alloc::string::String"|"String" => Some("crate::c_types::Str"), - "std::time::Duration" => Some("u64"), + "std::time::Duration"|"core::time::Duration" => Some("u64"), "std::time::SystemTime" => Some("u64"), "std::io::Error" => Some("crate::c_types::IOError"), @@ -913,11 +929,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[usize]" if is_ref => Some(""), "str" if is_ref => Some(""), - "String" => Some(""), + "alloc::string::String"|"String" => Some(""), // Note that we'll panic for String if is_ref, as we only have non-owned memory, we // cannot create a &String. - "std::time::Duration" => Some("std::time::Duration::from_secs("), + "std::time::Duration"|"core::time::Duration" => Some("std::time::Duration::from_secs("), "std::time::SystemTime" => Some("(::std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs("), "bech32::u5" => Some(""), @@ -979,9 +995,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[usize]" if is_ref => Some(".to_slice()"), "str" if is_ref => Some(".into_str()"), - "String" => Some(".into_string()"), + "alloc::string::String"|"String" => Some(".into_string()"), - "std::time::Duration" => Some(")"), + "std::time::Duration"|"core::time::Duration" => Some(")"), "std::time::SystemTime" => Some("))"), "bech32::u5" => Some(".into()"), @@ -1058,9 +1074,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[usize]" if is_ref => Some("local_"), "str" if is_ref => Some(""), - "String" => Some(""), + "alloc::string::String"|"String" => Some(""), - "std::time::Duration" => Some(""), + "std::time::Duration"|"core::time::Duration" => Some(""), "std::time::SystemTime" => Some(""), "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("), @@ -1127,10 +1143,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[usize]" if is_ref => Some(""), "str" if is_ref => Some(".into()"), - "String" if is_ref => Some(".as_str().into()"), - "String" => Some(".into()"), + "alloc::string::String"|"String" if is_ref => Some(".as_str().into()"), + "alloc::string::String"|"String" => Some(".into()"), - "std::time::Duration" => Some(".as_secs()"), + "std::time::Duration"|"core::time::Duration" => Some(".as_secs()"), "std::time::SystemTime" => Some(".duration_since(::std::time::SystemTime::UNIX_EPOCH).expect(\"Times must be post-1970\").as_secs()"), "std::io::Error" if !is_ref => Some(")"), diff --git a/lightning-c-bindings/Cargo.toml b/lightning-c-bindings/Cargo.toml index badaf9f..40d316e 100644 --- a/lightning-c-bindings/Cargo.toml +++ b/lightning-c-bindings/Cargo.toml @@ -18,9 +18,9 @@ crate-type = ["staticlib" bitcoin = "0.26" secp256k1 = { version = "0.20.1", features = ["global-context-less-secure"] } # Note that the following line is matched by genbindings to update the path -lightning = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "d4d322580994857b1222488f8467311d6db61482", features = ["allow_wallclock_use"] } -lightning-persister = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "d4d322580994857b1222488f8467311d6db61482" } -lightning-invoice = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "d4d322580994857b1222488f8467311d6db61482" } +lightning = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "3996eaab6e2eaf5fde9374b51d952c0edef5ea92", features = ["allow_wallclock_use"] } +lightning-persister = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "3996eaab6e2eaf5fde9374b51d952c0edef5ea92" } +lightning-invoice = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "3996eaab6e2eaf5fde9374b51d952c0edef5ea92" } [patch.crates-io] # Rust-Secp256k1 PR 279. Should be dropped once merged. diff --git a/lightning-c-bindings/demo.c b/lightning-c-bindings/demo.c index 2a45e46..a955630 100644 --- a/lightning-c-bindings/demo.c +++ b/lightning-c-bindings/demo.c @@ -35,6 +35,11 @@ LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) { return empty_htlc_vec; } +void never_handle_event(const void *this_arg, struct LDKEvent event) { + // Note that we never actually generate any events to handle in the code below. + assert(false); +} + int main() { uint8_t node_seed[32]; memset(node_seed, 0, 32); @@ -82,9 +87,9 @@ int main() { CVec_ChannelDetailsZ_free(channels); LDKEventsProvider prov = ChannelManager_as_EventsProvider(&cm); - LDKCVec_EventZ events = (prov.get_and_clear_pending_events)(prov.this_arg); - assert((unsigned long)events.data < 4096); // There's an offset, but it should still be an offset against null in the 0 page - assert(events.datalen == 0); + // Check that no events were generated by asserting if any events are passed to never_handle_event. + LDKEventHandler handler = { .handle_event = never_handle_event, .free = NULL }; + (prov.process_pending_events)(prov.this_arg, handler); ChannelManager_free(cm); KeysManager_free(keys); diff --git a/lightning-c-bindings/demo.cpp b/lightning-c-bindings/demo.cpp index 4bc3115..de1e46c 100644 --- a/lightning-c-bindings/demo.cpp +++ b/lightning-c-bindings/demo.cpp @@ -185,6 +185,15 @@ LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) { } } +struct EventQueue { + std::vector events; +}; +void handle_event(const void *this_arg, LDKEvent event) { + EventQueue* arg = (EventQueue*) this_arg; + arg->events.push_back(std::move(event)); +} + + uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) { return write((int)((long)this_arg), data.data, data.datalen); } @@ -419,16 +428,18 @@ int main() { LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1); while (true) { - LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg); - if (events->datalen == 1) { - assert(events->data[0].tag == LDKEvent_FundingGenerationReady); - assert(events->data[0].funding_generation_ready.user_channel_id == 42); - assert(events->data[0].funding_generation_ready.channel_value_satoshis == 40000); - assert(events->data[0].funding_generation_ready.output_script.datalen == 34); - assert(!memcmp(events->data[0].funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34)); + EventQueue queue; + LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL }; + ev1.process_pending_events(ev1.this_arg, handler); + if (queue.events.size() == 1) { + assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady); + assert(queue.events[0]->funding_generation_ready.user_channel_id == 42); + assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000); + assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34); + assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34)); LDKTransaction funding_transaction { .data = const_cast(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false }; - LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &events->data[0].funding_generation_ready.temporary_channel_id.data, funding_transaction); + LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction); assert(fund_res->result_ok); break; } @@ -485,28 +496,39 @@ int main() { // We opened the channel with 1000 push_msat: assert(ChannelDetails_get_outbound_capacity_msat(channel) == 40000*1000 - 1000); assert(ChannelDetails_get_inbound_capacity_msat(channel) == 1000); - assert(ChannelDetails_get_is_live(channel)); + assert(ChannelDetails_get_is_usable(channel)); break; } std::this_thread::yield(); } - LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1); LDKCOption_u64Z min_value = { .tag = LDKCOption_u64Z_Some, .some = 5000, }; - LDK::C2Tuple_PaymentHashPaymentSecretZ payment_hash_secret = ChannelManager_create_inbound_payment(&cm2, min_value, 3600, 43); + LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2, + KeysManager_as_KeysInterface(&keys2), + LDKCurrency_Bitcoin, min_value, + LDKStr { + .chars = (const uint8_t *)"Invoice Description", + .len = strlen("Invoice Description"), + .chars_is_owned = false + }); + assert(invoice->result_ok); + LDKThirtyTwoBytes payment_hash; + memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32); + { + LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1); LDK::LockedNetworkGraph graph_2_locked = NetGraphMsgHandler_read_locked_graph(&net_graph2); LDK::NetworkGraph graph_2_ref = LockedNetworkGraph_graph(&graph_2_locked); LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures { .inner = NULL, .is_owned = false }, &outbound_channels, LDKCVec_RouteHintHopZ { .data = NULL, .datalen = 0 - }, 5000, 10, logger1); + }, 5000, Invoice_min_final_cltv_expiry(invoice->contents.result), logger1); assert(route->result_ok); - LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash_secret->a, payment_hash_secret->b); + LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, Invoice_payment_secret(invoice->contents.result)); assert(send_res->result_ok); } @@ -519,9 +541,11 @@ int main() { // Check that we received the payment! LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2); while (true) { - LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg); - if (events->datalen == 1) { - assert(events->data[0].tag == LDKEvent_PendingHTLCsForwardable); + EventQueue queue; + LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL }; + ev2.process_pending_events(ev2.this_arg, handler); + if (queue.events.size() == 1) { + assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable); break; } std::this_thread::yield(); @@ -532,13 +556,15 @@ int main() { mons_updated = 0; LDKThirtyTwoBytes payment_preimage; { - LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg); - assert(events->datalen == 1); - assert(events->data[0].tag == LDKEvent_PaymentReceived); - assert(!memcmp(events->data[0].payment_received.payment_hash.data, payment_hash_secret->a.data, 32)); - assert(!memcmp(events->data[0].payment_received.payment_secret.data, payment_hash_secret->b.data, 32)); - assert(events->data[0].payment_received.amt == 5000); - memcpy(payment_preimage.data, events->data[0].payment_received.payment_preimage.data, 32); + EventQueue queue; + LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL }; + ev2.process_pending_events(ev2.this_arg, handler); + assert(queue.events.size() == 1); + assert(queue.events[0]->tag == LDKEvent_PaymentReceived); + assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32)); + assert(!memcmp(queue.events[0]->payment_received.payment_secret.data, Invoice_payment_secret(invoice->contents.result).data, 32)); + assert(queue.events[0]->payment_received.amt == 5000); + memcpy(payment_preimage.data, queue.events[0]->payment_received.payment_preimage.data, 32); assert(ChannelManager_claim_funds(&cm2, payment_preimage)); } PeerManager_process_events(&net2); @@ -547,10 +573,12 @@ int main() { std::this_thread::yield(); } { - LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg); - assert(events->datalen == 1); - assert(events->data[0].tag == LDKEvent_PaymentSent); - assert(!memcmp(events->data[0].payment_sent.payment_preimage.data, payment_preimage.data, 32)); + EventQueue queue; + LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL }; + ev1.process_pending_events(ev1.this_arg, handler); + assert(queue.events.size() == 1); + assert(queue.events[0]->tag == LDKEvent_PaymentSent); + assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32)); } conn.stop(); diff --git a/lightning-c-bindings/include/lightning.h b/lightning-c-bindings/include/lightning.h index 60acaae..455cae8 100644 --- a/lightning-c-bindings/include/lightning.h +++ b/lightning-c-bindings/include/lightning.h @@ -328,6 +328,14 @@ typedef enum LDKSemanticError { * The invoice contains multiple descriptions and/or description hashes which isn't allowed */ LDKSemanticError_MultipleDescriptions, + /** + * The invoice contains multiple payment secrets + */ + LDKSemanticError_MultiplePaymentSecrets, + /** + * The invoice's features are invalid + */ + LDKSemanticError_InvalidFeatures, /** * The recovery id doesn't fit the signature/pub key */ @@ -2426,15 +2434,11 @@ typedef enum LDKEvent_Tag { /** * Indicates an outbound payment we made succeeded (ie it made it all the way to its target * and we got back the payment preimage for it). - * Note that duplicative PaymentSent Events may be generated - it is your responsibility to - * deduplicate them by payment_preimage (which MUST be unique)! */ LDKEvent_PaymentSent, /** * Indicates an outbound payment we made failed. Probably some intermediary node dropped * something. You may wish to retry with a different route. - * Note that duplicative PaymentFailed Events may be generated - it is your responsibility to - * deduplicate them by payment_hash (which MUST be unique)! */ LDKEvent_PaymentFailed, /** @@ -2919,12 +2923,12 @@ typedef struct LDKBaseSign { */ struct LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ (*sign_holder_commitment_and_htlcs)(const void *this_arg, const struct LDKHolderCommitmentTransaction *NONNULL_PTR commitment_tx); /** - * Create a signature for the given input in a transaction spending an HTLC or commitment - * transaction output when our counterparty broadcasts an old state. + * Create a signature for the given input in a transaction spending an HTLC transaction output + * or a commitment transaction `to_local` output when our counterparty broadcasts an old state. * - * A justice transaction may claim multiples outputs at the same time if timelocks are + * A justice transaction may claim multiple outputs at the same time if timelocks are * similar, but only a signature for the input at index `input` should be signed for here. - * It may be called multiples time for same output(s) if a fee-bump is needed with regards + * It may be called multiple times for same output(s) if a fee-bump is needed with regards * to an upcoming timelock expiration. * * Amount is value of the output spent by this input, committed to in the BIP 143 signature. @@ -2933,12 +2937,28 @@ typedef struct LDKBaseSign { * revoked the state which they eventually broadcast. It's not a _holder_ secret key and does * not allow the spending of any funds by itself (you need our holder revocation_secret to do * so). + */ + struct LDKCResult_SignatureNoneZ (*sign_justice_revoked_output)(const void *this_arg, struct LDKTransaction justice_tx, uintptr_t input, uint64_t amount, const uint8_t (*per_commitment_key)[32]); + /** + * Create a signature for the given input in a transaction spending a commitment transaction + * HTLC output when our counterparty broadcasts an old state. * - * htlc holds HTLC elements (hash, timelock) if the output being spent is a HTLC output, thus - * changing the format of the witness script (which is committed to in the BIP 143 - * signatures). + * A justice transaction may claim multiple outputs at the same time if timelocks are + * similar, but only a signature for the input at index `input` should be signed for here. + * It may be called multiple times for same output(s) if a fee-bump is needed with regards + * to an upcoming timelock expiration. + * + * Amount is value of the output spent by this input, committed to in the BIP 143 signature. + * + * per_commitment_key is revocation secret which was provided by our counterparty when they + * revoked the state which they eventually broadcast. It's not a _holder_ secret key and does + * not allow the spending of any funds by itself (you need our holder revocation_secret to do + * so). + * + * htlc holds HTLC elements (hash, timelock), thus changing the format of the witness script + * (which is committed to in the BIP 143 signatures). */ - struct LDKCResult_SignatureNoneZ (*sign_justice_transaction)(const void *this_arg, struct LDKTransaction justice_tx, uintptr_t input, uint64_t amount, const uint8_t (*per_commitment_key)[32], const struct LDKHTLCOutputInCommitment *NONNULL_PTR htlc); + struct LDKCResult_SignatureNoneZ (*sign_justice_revoked_htlc)(const void *this_arg, struct LDKTransaction justice_tx, uintptr_t input, uint64_t amount, const uint8_t (*per_commitment_key)[32], const struct LDKHTLCOutputInCommitment *NONNULL_PTR htlc); /** * Create a signature for a claiming transaction for a HTLC output on a counterparty's commitment * transaction, either offered or received. @@ -3136,6 +3156,39 @@ typedef struct MUST_USE_STRUCT LDKRouteHop { bool is_owned; } LDKRouteHop; +/** + * The contents of CResult_RouteHopDecodeErrorZ + */ +typedef union LDKCResult_RouteHopDecodeErrorZPtr { + /** + * A pointer to the contents in the success state. + * Reading from this pointer when `result_ok` is not set is undefined. + */ + struct LDKRouteHop *result; + /** + * A pointer to the contents in the error state. + * Reading from this pointer when `result_ok` is set is undefined. + */ + struct LDKDecodeError *err; +} LDKCResult_RouteHopDecodeErrorZPtr; + +/** + * A CResult_RouteHopDecodeErrorZ represents the result of a fallible operation, + * containing a crate::lightning::routing::router::RouteHop on success and a crate::lightning::ln::msgs::DecodeError on failure. + * `result_ok` indicates the overall state, and the contents are provided via `contents`. + */ +typedef struct LDKCResult_RouteHopDecodeErrorZ { + /** + * The contents of this CResult_RouteHopDecodeErrorZ, accessible via either + * `err` or `result` depending on the state of `result_ok`. + */ + union LDKCResult_RouteHopDecodeErrorZPtr contents; + /** + * Whether this CResult_RouteHopDecodeErrorZ represents a success state. + */ + bool result_ok; +} LDKCResult_RouteHopDecodeErrorZ; + /** * A dynamically-allocated array of crate::lightning::routing::router::RouteHops of arbitrary size. * This corresponds to std::vector in C++ @@ -5197,6 +5250,39 @@ typedef struct LDKCResult_CResult_NetAddressu8ZDecodeErrorZ { bool result_ok; } LDKCResult_CResult_NetAddressu8ZDecodeErrorZ; +/** + * The contents of CResult_NetAddressDecodeErrorZ + */ +typedef union LDKCResult_NetAddressDecodeErrorZPtr { + /** + * A pointer to the contents in the success state. + * Reading from this pointer when `result_ok` is not set is undefined. + */ + struct LDKNetAddress *result; + /** + * A pointer to the contents in the error state. + * Reading from this pointer when `result_ok` is set is undefined. + */ + struct LDKDecodeError *err; +} LDKCResult_NetAddressDecodeErrorZPtr; + +/** + * A CResult_NetAddressDecodeErrorZ represents the result of a fallible operation, + * containing a crate::lightning::ln::msgs::NetAddress on success and a crate::lightning::ln::msgs::DecodeError on failure. + * `result_ok` indicates the overall state, and the contents are provided via `contents`. + */ +typedef struct LDKCResult_NetAddressDecodeErrorZ { + /** + * The contents of this CResult_NetAddressDecodeErrorZ, accessible via either + * `err` or `result` depending on the state of `result_ok`. + */ + union LDKCResult_NetAddressDecodeErrorZPtr contents; + /** + * Whether this CResult_NetAddressDecodeErrorZ represents a success state. + */ + bool result_ok; +} LDKCResult_NetAddressDecodeErrorZ; + /** @@ -6610,6 +6696,72 @@ typedef struct LDKCResult_InvoiceSignOrCreationErrorZ { bool result_ok; } LDKCResult_InvoiceSignOrCreationErrorZ; +/** + * The contents of CResult_DelayedPaymentOutputDescriptorDecodeErrorZ + */ +typedef union LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr { + /** + * A pointer to the contents in the success state. + * Reading from this pointer when `result_ok` is not set is undefined. + */ + struct LDKDelayedPaymentOutputDescriptor *result; + /** + * A pointer to the contents in the error state. + * Reading from this pointer when `result_ok` is set is undefined. + */ + struct LDKDecodeError *err; +} LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr; + +/** + * A CResult_DelayedPaymentOutputDescriptorDecodeErrorZ represents the result of a fallible operation, + * containing a crate::lightning::chain::keysinterface::DelayedPaymentOutputDescriptor on success and a crate::lightning::ln::msgs::DecodeError on failure. + * `result_ok` indicates the overall state, and the contents are provided via `contents`. + */ +typedef struct LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + /** + * The contents of this CResult_DelayedPaymentOutputDescriptorDecodeErrorZ, accessible via either + * `err` or `result` depending on the state of `result_ok`. + */ + union LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr contents; + /** + * Whether this CResult_DelayedPaymentOutputDescriptorDecodeErrorZ represents a success state. + */ + bool result_ok; +} LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ; + +/** + * The contents of CResult_StaticPaymentOutputDescriptorDecodeErrorZ + */ +typedef union LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZPtr { + /** + * A pointer to the contents in the success state. + * Reading from this pointer when `result_ok` is not set is undefined. + */ + struct LDKStaticPaymentOutputDescriptor *result; + /** + * A pointer to the contents in the error state. + * Reading from this pointer when `result_ok` is set is undefined. + */ + struct LDKDecodeError *err; +} LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZPtr; + +/** + * A CResult_StaticPaymentOutputDescriptorDecodeErrorZ represents the result of a fallible operation, + * containing a crate::lightning::chain::keysinterface::StaticPaymentOutputDescriptor on success and a crate::lightning::ln::msgs::DecodeError on failure. + * `result_ok` indicates the overall state, and the contents are provided via `contents`. + */ +typedef struct LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ { + /** + * The contents of this CResult_StaticPaymentOutputDescriptorDecodeErrorZ, accessible via either + * `err` or `result` depending on the state of `result_ok`. + */ + union LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZPtr contents; + /** + * Whether this CResult_StaticPaymentOutputDescriptorDecodeErrorZ represents a success state. + */ + bool result_ok; +} LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ; + /** * The contents of CResult_SpendableOutputDescriptorDecodeErrorZ */ @@ -7600,7 +7752,52 @@ typedef struct LDKMessageSendEventsProvider { } LDKMessageSendEventsProvider; /** - * A trait indicating an object may generate events + * A trait implemented for objects handling events from [`EventsProvider`]. + */ +typedef struct LDKEventHandler { + /** + * An opaque pointer which is passed to your function implementations as an argument. + * This has no meaning in the LDK, and can be NULL or any other value. + */ + void *this_arg; + /** + * Handles the given [`Event`]. + * + * See [`EventsProvider`] for details that must be considered when implementing this method. + */ + void (*handle_event)(const void *this_arg, struct LDKEvent event); + /** + * Frees any resources associated with this object given its this_arg pointer. + * Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed. + */ + void (*free)(void *this_arg); +} LDKEventHandler; + +/** + * A trait indicating an object may generate events. + * + * Events are processed by passing an [`EventHandler`] to [`process_pending_events`]. + * + * # Requirements + * + * See [`process_pending_events`] for requirements around event processing. + * + * When using this trait, [`process_pending_events`] will call [`handle_event`] for each pending + * event since the last invocation. The handler must either act upon the event immediately + * or preserve it for later handling. + * + * Note, handlers may call back into the provider and thus deadlocking must be avoided. Be sure to + * consult the provider's documentation on the implication of processing events and how a handler + * may safely use the provider (e.g., see [`ChannelManager::process_pending_events`] and + * [`ChainMonitor::process_pending_events`]). + * + * (C-not implementable) As there is likely no reason for a user to implement this trait on their + * own type(s). + * + * [`process_pending_events`]: Self::process_pending_events + * [`handle_event`]: EventHandler::handle_event + * [`ChannelManager::process_pending_events`]: crate::ln::channelmanager::ChannelManager#method.process_pending_events + * [`ChainMonitor::process_pending_events`]: crate::chain::chainmonitor::ChainMonitor#method.process_pending_events */ typedef struct LDKEventsProvider { /** @@ -7609,10 +7806,13 @@ typedef struct LDKEventsProvider { */ void *this_arg; /** - * Gets the list of pending events which were generated by previous actions, clearing the list - * in the process. + * Processes any events generated since the last call using the given event handler. + * + * Subsequent calls must only process new events. However, handlers must be capable of handling + * duplicate events across process restarts. This may occur if the provider was recovered from + * an old state (i.e., it hadn't been successfully persisted after processing pending events). */ - struct LDKCVec_EventZ (*get_and_clear_pending_events)(const void *this_arg); + void (*process_pending_events)(const void *this_arg, struct LDKEventHandler handler); /** * Frees any resources associated with this object given its this_arg pointer. * Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed. @@ -8729,6 +8929,8 @@ extern const uint64_t MIN_RELAY_FEE_SAT_PER_1000_WEIGHT; extern const uint64_t CLOSED_CHANNEL_UPDATE_ID; +extern const uint32_t ANTI_REORG_DELAY; + extern const uint16_t BREAKDOWN_TIMEOUT; extern const uint16_t MIN_CLTV_EXPIRY_DELTA; @@ -9595,6 +9797,27 @@ struct LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ CResult_C2Tuple_B */ void CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_free(struct LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ _res); +/** + * Creates a new CResult_RouteHopDecodeErrorZ in the success state. + */ +struct LDKCResult_RouteHopDecodeErrorZ CResult_RouteHopDecodeErrorZ_ok(struct LDKRouteHop o); + +/** + * Creates a new CResult_RouteHopDecodeErrorZ in the error state. + */ +struct LDKCResult_RouteHopDecodeErrorZ CResult_RouteHopDecodeErrorZ_err(struct LDKDecodeError e); + +/** + * Frees any resources used by the CResult_RouteHopDecodeErrorZ. + */ +void CResult_RouteHopDecodeErrorZ_free(struct LDKCResult_RouteHopDecodeErrorZ _res); + +/** + * Creates a new CResult_RouteHopDecodeErrorZ which has the same data as `orig` + * but with all dynamically-allocated buffers duplicated in new buffers. + */ +struct LDKCResult_RouteHopDecodeErrorZ CResult_RouteHopDecodeErrorZ_clone(const struct LDKCResult_RouteHopDecodeErrorZ *NONNULL_PTR orig); + /** * Frees the buffer pointed to by `data` if `datalen` is non-0. */ @@ -10072,6 +10295,27 @@ void CResult_CResult_NetAddressu8ZDecodeErrorZ_free(struct LDKCResult_CResult_Ne */ struct LDKCResult_CResult_NetAddressu8ZDecodeErrorZ CResult_CResult_NetAddressu8ZDecodeErrorZ_clone(const struct LDKCResult_CResult_NetAddressu8ZDecodeErrorZ *NONNULL_PTR orig); +/** + * Creates a new CResult_NetAddressDecodeErrorZ in the success state. + */ +struct LDKCResult_NetAddressDecodeErrorZ CResult_NetAddressDecodeErrorZ_ok(struct LDKNetAddress o); + +/** + * Creates a new CResult_NetAddressDecodeErrorZ in the error state. + */ +struct LDKCResult_NetAddressDecodeErrorZ CResult_NetAddressDecodeErrorZ_err(struct LDKDecodeError e); + +/** + * Frees any resources used by the CResult_NetAddressDecodeErrorZ. + */ +void CResult_NetAddressDecodeErrorZ_free(struct LDKCResult_NetAddressDecodeErrorZ _res); + +/** + * Creates a new CResult_NetAddressDecodeErrorZ which has the same data as `orig` + * but with all dynamically-allocated buffers duplicated in new buffers. + */ +struct LDKCResult_NetAddressDecodeErrorZ CResult_NetAddressDecodeErrorZ_clone(const struct LDKCResult_NetAddressDecodeErrorZ *NONNULL_PTR orig); + /** * Frees the buffer pointed to by `data` if `datalen` is non-0. */ @@ -10764,6 +11008,48 @@ void CResult_InvoiceSignOrCreationErrorZ_free(struct LDKCResult_InvoiceSignOrCre */ struct LDKCResult_InvoiceSignOrCreationErrorZ CResult_InvoiceSignOrCreationErrorZ_clone(const struct LDKCResult_InvoiceSignOrCreationErrorZ *NONNULL_PTR orig); +/** + * Creates a new CResult_DelayedPaymentOutputDescriptorDecodeErrorZ in the success state. + */ +struct LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_ok(struct LDKDelayedPaymentOutputDescriptor o); + +/** + * Creates a new CResult_DelayedPaymentOutputDescriptorDecodeErrorZ in the error state. + */ +struct LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_err(struct LDKDecodeError e); + +/** + * Frees any resources used by the CResult_DelayedPaymentOutputDescriptorDecodeErrorZ. + */ +void CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_free(struct LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ _res); + +/** + * Creates a new CResult_DelayedPaymentOutputDescriptorDecodeErrorZ which has the same data as `orig` + * but with all dynamically-allocated buffers duplicated in new buffers. + */ +struct LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_clone(const struct LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ *NONNULL_PTR orig); + +/** + * Creates a new CResult_StaticPaymentOutputDescriptorDecodeErrorZ in the success state. + */ +struct LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ CResult_StaticPaymentOutputDescriptorDecodeErrorZ_ok(struct LDKStaticPaymentOutputDescriptor o); + +/** + * Creates a new CResult_StaticPaymentOutputDescriptorDecodeErrorZ in the error state. + */ +struct LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ CResult_StaticPaymentOutputDescriptorDecodeErrorZ_err(struct LDKDecodeError e); + +/** + * Frees any resources used by the CResult_StaticPaymentOutputDescriptorDecodeErrorZ. + */ +void CResult_StaticPaymentOutputDescriptorDecodeErrorZ_free(struct LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ _res); + +/** + * Creates a new CResult_StaticPaymentOutputDescriptorDecodeErrorZ which has the same data as `orig` + * but with all dynamically-allocated buffers duplicated in new buffers. + */ +struct LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ CResult_StaticPaymentOutputDescriptorDecodeErrorZ_clone(const struct LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ *NONNULL_PTR orig); + /** * Creates a new CResult_SpendableOutputDescriptorDecodeErrorZ in the success state. */ @@ -11129,6 +11415,11 @@ void MessageSendEventsProvider_free(struct LDKMessageSendEventsProvider this_ptr */ void EventsProvider_free(struct LDKEventsProvider this_ptr); +/** + * Calls the free function if one is set + */ +void EventHandler_free(struct LDKEventHandler this_ptr); + /** * Frees any resources used by the APIError */ @@ -11162,6 +11453,17 @@ bool verify(struct LDKu8slice msg, struct LDKStr sig, struct LDKPublicKey pk); */ enum LDKLevel Level_clone(const enum LDKLevel *NONNULL_PTR orig); +/** + * Checks if two Levels contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + */ +bool Level_eq(const enum LDKLevel *NONNULL_PTR a, const enum LDKLevel *NONNULL_PTR b); + +/** + * Checks if two Levels contain equal inner contents. + */ +uint64_t Level_hash(const enum LDKLevel *NONNULL_PTR o); + /** * Returns the most verbose logging level. */ @@ -11357,50 +11659,6 @@ uint16_t ChannelHandshakeLimits_get_min_max_accepted_htlcs(const struct LDKChann */ void ChannelHandshakeLimits_set_min_max_accepted_htlcs(struct LDKChannelHandshakeLimits *NONNULL_PTR this_ptr, uint16_t val); -/** - * Outputs below a certain value will not be added to on-chain transactions. The dust value is - * required to always be higher than this value so this only applies to HTLC outputs (and - * potentially to-self outputs before any payments have been made). - * Thus, HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. - * This setting allows you to set a minimum dust limit for their commitment transactions, - * reflecting the reality that tiny outputs are not considered standard transactions and will - * not propagate through the Bitcoin network. - * - * Default value: 546, the current dust limit on the Bitcoin network. - */ -uint64_t ChannelHandshakeLimits_get_min_dust_limit_satoshis(const struct LDKChannelHandshakeLimits *NONNULL_PTR this_ptr); - -/** - * Outputs below a certain value will not be added to on-chain transactions. The dust value is - * required to always be higher than this value so this only applies to HTLC outputs (and - * potentially to-self outputs before any payments have been made). - * Thus, HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. - * This setting allows you to set a minimum dust limit for their commitment transactions, - * reflecting the reality that tiny outputs are not considered standard transactions and will - * not propagate through the Bitcoin network. - * - * Default value: 546, the current dust limit on the Bitcoin network. - */ -void ChannelHandshakeLimits_set_min_dust_limit_satoshis(struct LDKChannelHandshakeLimits *NONNULL_PTR this_ptr, uint64_t val); - -/** - * Maximum allowed threshold above which outputs will not be generated in their commitment - * transactions. - * HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. - * - * Default value: u64::max_value. - */ -uint64_t ChannelHandshakeLimits_get_max_dust_limit_satoshis(const struct LDKChannelHandshakeLimits *NONNULL_PTR this_ptr); - -/** - * Maximum allowed threshold above which outputs will not be generated in their commitment - * transactions. - * HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. - * - * Default value: u64::max_value. - */ -void ChannelHandshakeLimits_set_max_dust_limit_satoshis(struct LDKChannelHandshakeLimits *NONNULL_PTR this_ptr, uint64_t val); - /** * Before a channel is usable the funding transaction will need to be confirmed by at least a * certain number of blocks, specified by the node which is not the funder (as the funder can @@ -11464,7 +11722,7 @@ void ChannelHandshakeLimits_set_their_to_self_delay(struct LDKChannelHandshakeLi /** * Constructs a new ChannelHandshakeLimits given each field */ -MUST_USE_RES struct LDKChannelHandshakeLimits ChannelHandshakeLimits_new(uint64_t min_funding_satoshis_arg, uint64_t max_htlc_minimum_msat_arg, uint64_t min_max_htlc_value_in_flight_msat_arg, uint64_t max_channel_reserve_satoshis_arg, uint16_t min_max_accepted_htlcs_arg, uint64_t min_dust_limit_satoshis_arg, uint64_t max_dust_limit_satoshis_arg, uint32_t max_minimum_depth_arg, bool force_announced_channel_preference_arg, uint16_t their_to_self_delay_arg); +MUST_USE_RES struct LDKChannelHandshakeLimits ChannelHandshakeLimits_new(uint64_t min_funding_satoshis_arg, uint64_t max_htlc_minimum_msat_arg, uint64_t min_max_htlc_value_in_flight_msat_arg, uint64_t max_channel_reserve_satoshis_arg, uint16_t min_max_accepted_htlcs_arg, uint32_t max_minimum_depth_arg, bool force_announced_channel_preference_arg, uint16_t their_to_self_delay_arg); /** * Creates a copy of the ChannelHandshakeLimits @@ -12074,6 +12332,18 @@ MUST_USE_RES struct LDKOutPoint OutPoint_new(struct LDKThirtyTwoBytes txid_arg, */ struct LDKOutPoint OutPoint_clone(const struct LDKOutPoint *NONNULL_PTR orig); +/** + * Checks if two OutPoints contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool OutPoint_eq(const struct LDKOutPoint *NONNULL_PTR a, const struct LDKOutPoint *NONNULL_PTR b); + +/** + * Checks if two OutPoints contain equal inner contents. + */ +uint64_t OutPoint_hash(const struct LDKOutPoint *NONNULL_PTR o); + /** * Convert an `OutPoint` to a lightning channel id. */ @@ -12177,6 +12447,16 @@ MUST_USE_RES struct LDKDelayedPaymentOutputDescriptor DelayedPaymentOutputDescri */ struct LDKDelayedPaymentOutputDescriptor DelayedPaymentOutputDescriptor_clone(const struct LDKDelayedPaymentOutputDescriptor *NONNULL_PTR orig); +/** + * Serialize the DelayedPaymentOutputDescriptor object into a byte array which can be read by DelayedPaymentOutputDescriptor_read + */ +struct LDKCVec_u8Z DelayedPaymentOutputDescriptor_write(const struct LDKDelayedPaymentOutputDescriptor *NONNULL_PTR obj); + +/** + * Read a DelayedPaymentOutputDescriptor from a byte array, created by DelayedPaymentOutputDescriptor_write + */ +struct LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ DelayedPaymentOutputDescriptor_read(struct LDKu8slice ser); + /** * Frees any resources used by the StaticPaymentOutputDescriptor, if is_owned is set and inner is non-NULL. */ @@ -12231,6 +12511,16 @@ MUST_USE_RES struct LDKStaticPaymentOutputDescriptor StaticPaymentOutputDescript */ struct LDKStaticPaymentOutputDescriptor StaticPaymentOutputDescriptor_clone(const struct LDKStaticPaymentOutputDescriptor *NONNULL_PTR orig); +/** + * Serialize the StaticPaymentOutputDescriptor object into a byte array which can be read by StaticPaymentOutputDescriptor_read + */ +struct LDKCVec_u8Z StaticPaymentOutputDescriptor_write(const struct LDKStaticPaymentOutputDescriptor *NONNULL_PTR obj); + +/** + * Read a StaticPaymentOutputDescriptor from a byte array, created by StaticPaymentOutputDescriptor_write + */ +struct LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ StaticPaymentOutputDescriptor_read(struct LDKu8slice ser); + /** * Frees any resources used by the SpendableOutputDescriptor */ @@ -12577,6 +12867,24 @@ const uint8_t (*ChannelDetails_get_channel_id(const struct LDKChannelDetails *NO */ void ChannelDetails_set_channel_id(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKThirtyTwoBytes val); +/** + * The Channel's funding transaction output, if we've negotiated the funding transaction with + * our counterparty already. + * + * Note that, if this has been set, `channel_id` will be equivalent to + * `funding_txo.unwrap().to_channel_id()`. + */ +struct LDKOutPoint ChannelDetails_get_funding_txo(const struct LDKChannelDetails *NONNULL_PTR this_ptr); + +/** + * The Channel's funding transaction output, if we've negotiated the funding transaction with + * our counterparty already. + * + * Note that, if this has been set, `channel_id` will be equivalent to + * `funding_txo.unwrap().to_channel_id()`. + */ +void ChannelDetails_set_funding_txo(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKOutPoint val); + /** * The position of the funding transaction in the chain. None if the funding transaction has * not yet been confirmed and the channel fully opened. @@ -12667,17 +12975,59 @@ uint64_t ChannelDetails_get_inbound_capacity_msat(const struct LDKChannelDetails */ void ChannelDetails_set_inbound_capacity_msat(struct LDKChannelDetails *NONNULL_PTR this_ptr, uint64_t val); +/** + * True if the channel was initiated (and thus funded) by us. + */ +bool ChannelDetails_get_is_outbound(const struct LDKChannelDetails *NONNULL_PTR this_ptr); + +/** + * True if the channel was initiated (and thus funded) by us. + */ +void ChannelDetails_set_is_outbound(struct LDKChannelDetails *NONNULL_PTR this_ptr, bool val); + +/** + * True if the channel is confirmed, funding_locked messages have been exchanged, and the + * channel is not currently being shut down. `funding_locked` message exchange implies the + * required confirmation count has been reached (and we were connected to the peer at some + * point after the funding transaction received enough confirmations). + */ +bool ChannelDetails_get_is_funding_locked(const struct LDKChannelDetails *NONNULL_PTR this_ptr); + +/** + * True if the channel is confirmed, funding_locked messages have been exchanged, and the + * channel is not currently being shut down. `funding_locked` message exchange implies the + * required confirmation count has been reached (and we were connected to the peer at some + * point after the funding transaction received enough confirmations). + */ +void ChannelDetails_set_is_funding_locked(struct LDKChannelDetails *NONNULL_PTR this_ptr, bool val); + /** * True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b) - * the peer is connected, and (c) no monitor update failure is pending resolution. + * the peer is connected, (c) no monitor update failure is pending resolution, and (d) the + * channel is not currently negotiating a shutdown. + * + * This is a strict superset of `is_funding_locked`. */ -bool ChannelDetails_get_is_live(const struct LDKChannelDetails *NONNULL_PTR this_ptr); +bool ChannelDetails_get_is_usable(const struct LDKChannelDetails *NONNULL_PTR this_ptr); /** * True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b) - * the peer is connected, and (c) no monitor update failure is pending resolution. + * the peer is connected, (c) no monitor update failure is pending resolution, and (d) the + * channel is not currently negotiating a shutdown. + * + * This is a strict superset of `is_funding_locked`. + */ +void ChannelDetails_set_is_usable(struct LDKChannelDetails *NONNULL_PTR this_ptr, bool val); + +/** + * True if this channel is (or will be) publicly-announced. + */ +bool ChannelDetails_get_is_public(const struct LDKChannelDetails *NONNULL_PTR this_ptr); + +/** + * True if this channel is (or will be) publicly-announced. */ -void ChannelDetails_set_is_live(struct LDKChannelDetails *NONNULL_PTR this_ptr, bool val); +void ChannelDetails_set_is_public(struct LDKChannelDetails *NONNULL_PTR this_ptr, bool val); /** * Creates a copy of the ChannelDetails @@ -12742,8 +13092,9 @@ MUST_USE_RES struct LDKCVec_ChannelDetailsZ ChannelManager_list_channels(const s * Gets the list of usable channels, in random order. Useful as an argument to * get_route to ensure non-announced channels are used. * - * These are guaranteed to have their is_live value set to true, see the documentation for - * ChannelDetails::is_live for more info on exactly what the criteria are. + * These are guaranteed to have their [`ChannelDetails::is_usable`] value set to true, see the + * documentation for [`ChannelDetails::is_usable`] for more info on exactly what the criteria + * are. */ MUST_USE_RES struct LDKCVec_ChannelDetailsZ ChannelManager_list_usable_channels(const struct LDKChannelManager *NONNULL_PTR this_arg); @@ -12830,23 +13181,30 @@ MUST_USE_RES struct LDKCResult_NonePaymentSendFailureZ ChannelManager_send_payme * Note that this includes RBF or similar transaction replacement strategies - lightning does * not currently support replacing a funding transaction on an existing channel. Instead, * create a new channel with a conflicting funding transaction. + * + * [`Event::FundingGenerationReady`]: crate::util::events::Event::FundingGenerationReady */ MUST_USE_RES struct LDKCResult_NoneAPIErrorZ ChannelManager_funding_transaction_generated(const struct LDKChannelManager *NONNULL_PTR this_arg, const uint8_t (*temporary_channel_id)[32], struct LDKTransaction funding_transaction); /** - * Generates a signed node_announcement from the given arguments and creates a - * BroadcastNodeAnnouncement event. Note that such messages will be ignored unless peers have - * seen a channel_announcement from us (ie unless we have public channels open). + * Regenerates channel_announcements and generates a signed node_announcement from the given + * arguments, providing them in corresponding events via + * [`get_and_clear_pending_msg_events`], if at least one public channel has been confirmed + * on-chain. This effectively re-broadcasts all channel announcements and sends our node + * announcement to ensure that the lightning P2P network is aware of the channels we have and + * our network addresses. + * + * `rgb` is a node \"color\" and `alias` is a printable human-readable string to describe this + * node to humans. They carry no in-protocol meaning. * - * RGB is a node \"color\" and alias is a printable human-readable string to describe this node - * to humans. They carry no in-protocol meaning. + * `addresses` represent the set (possibly empty) of socket addresses on which this node + * accepts incoming connections. These will be included in the node_announcement, publicly + * tying these addresses together and to this node. If you wish to preserve user privacy, + * addresses should likely contain only Tor Onion addresses. * - * addresses represent the set (possibly empty) of socket addresses on which this node accepts - * incoming connections. These will be broadcast to the network, publicly tying these - * addresses together. If you wish to preserve user privacy, addresses should likely contain - * only Tor Onion addresses. + * Panics if `addresses` is absurdly large (more than 500). * - * Panics if addresses is absurdly large (more than 500). + * [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events */ void ChannelManager_broadcast_node_announcement(const struct LDKChannelManager *NONNULL_PTR this_arg, struct LDKThreeBytes rgb, struct LDKThirtyTwoBytes alias, struct LDKCVec_NetAddressZ addresses); @@ -12969,7 +13327,7 @@ MUST_USE_RES struct LDKC2Tuple_PaymentHashPaymentSecretZ ChannelManager_create_i * `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for * in excess of the current time. This should roughly match the expiry time set in the invoice. * After this many seconds, we will remove the inbound payment, resulting in any attempts to - * pay the invoice failing. The BOLT spec suggests 7,200 secs as a default validity time for + * pay the invoice failing. The BOLT spec suggests 3,600 secs as a default validity time for * invoices when no timeout is set. * * Note that we use block header time to time-out pending inbound payments (with some margin @@ -14279,6 +14637,11 @@ struct LDKCVec_u8Z NetAddress_write(const struct LDKNetAddress *NONNULL_PTR obj) */ struct LDKCResult_CResult_NetAddressu8ZDecodeErrorZ Result_read(struct LDKu8slice ser); +/** + * Read a NetAddress from a byte array, created by NetAddress_write + */ +struct LDKCResult_NetAddressDecodeErrorZ NetAddress_read(struct LDKu8slice ser); + /** * Frees any resources used by the UnsignedNodeAnnouncement, if is_owned is set and inner is non-NULL. */ @@ -16271,6 +16634,34 @@ MUST_USE_RES struct LDKCResult_CVec_SignatureZNoneZ TrustedCommitmentTransaction */ uint64_t get_commitment_transaction_number_obscure_factor(struct LDKPublicKey broadcaster_payment_basepoint, struct LDKPublicKey countersignatory_payment_basepoint, bool outbound_from_broadcaster); +/** + * Checks if two InitFeaturess contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool InitFeatures_eq(const struct LDKInitFeatures *NONNULL_PTR a, const struct LDKInitFeatures *NONNULL_PTR b); + +/** + * Checks if two NodeFeaturess contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool NodeFeatures_eq(const struct LDKNodeFeatures *NONNULL_PTR a, const struct LDKNodeFeatures *NONNULL_PTR b); + +/** + * Checks if two ChannelFeaturess contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool ChannelFeatures_eq(const struct LDKChannelFeatures *NONNULL_PTR a, const struct LDKChannelFeatures *NONNULL_PTR b); + +/** + * Checks if two InvoiceFeaturess contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool InvoiceFeatures_eq(const struct LDKInvoiceFeatures *NONNULL_PTR a, const struct LDKInvoiceFeatures *NONNULL_PTR b); + /** * Creates a copy of the InitFeatures */ @@ -16351,6 +16742,21 @@ MUST_USE_RES struct LDKInvoiceFeatures InvoiceFeatures_empty(void); */ MUST_USE_RES struct LDKInvoiceFeatures InvoiceFeatures_known(void); +/** + * Returns whether the `payment_secret` feature is supported. + */ +MUST_USE_RES bool InitFeatures_supports_payment_secret(const struct LDKInitFeatures *NONNULL_PTR this_arg); + +/** + * Returns whether the `payment_secret` feature is supported. + */ +MUST_USE_RES bool NodeFeatures_supports_payment_secret(const struct LDKNodeFeatures *NONNULL_PTR this_arg); + +/** + * Returns whether the `payment_secret` feature is supported. + */ +MUST_USE_RES bool InvoiceFeatures_supports_payment_secret(const struct LDKInvoiceFeatures *NONNULL_PTR this_arg); + /** * Serialize the InitFeatures object into a byte array which can be read by InitFeatures_read */ @@ -16476,6 +16882,16 @@ MUST_USE_RES struct LDKRouteHop RouteHop_new(struct LDKPublicKey pubkey_arg, str */ struct LDKRouteHop RouteHop_clone(const struct LDKRouteHop *NONNULL_PTR orig); +/** + * Serialize the RouteHop object into a byte array which can be read by RouteHop_read + */ +struct LDKCVec_u8Z RouteHop_write(const struct LDKRouteHop *NONNULL_PTR obj); + +/** + * Read a RouteHop from a byte array, created by RouteHop_write + */ +struct LDKCResult_RouteHopDecodeErrorZ RouteHop_read(struct LDKu8slice ser); + /** * Frees any resources used by the Route, if is_owned is set and inner is non-NULL. */ @@ -16581,6 +16997,13 @@ void RouteHintHop_set_htlc_maximum_msat(struct LDKRouteHintHop *NONNULL_PTR this */ MUST_USE_RES struct LDKRouteHintHop RouteHintHop_new(struct LDKPublicKey src_node_id_arg, uint64_t short_channel_id_arg, struct LDKRoutingFees fees_arg, uint16_t cltv_expiry_delta_arg, struct LDKCOption_u64Z htlc_minimum_msat_arg, struct LDKCOption_u64Z htlc_maximum_msat_arg); +/** + * Checks if two RouteHintHops contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool RouteHintHop_eq(const struct LDKRouteHintHop *NONNULL_PTR a, const struct LDKRouteHintHop *NONNULL_PTR b); + /** * Creates a copy of the RouteHintHop */ @@ -16913,20 +17336,27 @@ void RoutingFees_set_proportional_millionths(struct LDKRoutingFees *NONNULL_PTR MUST_USE_RES struct LDKRoutingFees RoutingFees_new(uint32_t base_msat_arg, uint32_t proportional_millionths_arg); /** - * Creates a copy of the RoutingFees + * Checks if two RoutingFeess contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. */ -struct LDKRoutingFees RoutingFees_clone(const struct LDKRoutingFees *NONNULL_PTR orig); +bool RoutingFees_eq(const struct LDKRoutingFees *NONNULL_PTR a, const struct LDKRoutingFees *NONNULL_PTR b); /** - * Read a RoutingFees from a byte array, created by RoutingFees_write + * Creates a copy of the RoutingFees */ -struct LDKCResult_RoutingFeesDecodeErrorZ RoutingFees_read(struct LDKu8slice ser); +struct LDKRoutingFees RoutingFees_clone(const struct LDKRoutingFees *NONNULL_PTR orig); /** * Serialize the RoutingFees object into a byte array which can be read by RoutingFees_read */ struct LDKCVec_u8Z RoutingFees_write(const struct LDKRoutingFees *NONNULL_PTR obj); +/** + * Read a RoutingFees from a byte array, created by RoutingFees_write + */ +struct LDKCResult_RoutingFeesDecodeErrorZ RoutingFees_read(struct LDKu8slice ser); + /** * Frees any resources used by the NodeAnnouncementInfo, if is_owned is set and inner is non-NULL. */ @@ -17212,6 +17642,13 @@ void check_platform(void); */ void Invoice_free(struct LDKInvoice this_obj); +/** + * Checks if two Invoices contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool Invoice_eq(const struct LDKInvoice *NONNULL_PTR a, const struct LDKInvoice *NONNULL_PTR b); + /** * Creates a copy of the Invoice */ @@ -17222,6 +17659,13 @@ struct LDKInvoice Invoice_clone(const struct LDKInvoice *NONNULL_PTR orig); */ void SignedRawInvoice_free(struct LDKSignedRawInvoice this_obj); +/** + * Checks if two SignedRawInvoices contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool SignedRawInvoice_eq(const struct LDKSignedRawInvoice *NONNULL_PTR a, const struct LDKSignedRawInvoice *NONNULL_PTR b); + /** * Creates a copy of the SignedRawInvoice */ @@ -17242,6 +17686,13 @@ struct LDKRawDataPart RawInvoice_get_data(const struct LDKRawInvoice *NONNULL_PT */ void RawInvoice_set_data(struct LDKRawInvoice *NONNULL_PTR this_ptr, struct LDKRawDataPart val); +/** + * Checks if two RawInvoices contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool RawInvoice_eq(const struct LDKRawInvoice *NONNULL_PTR a, const struct LDKRawInvoice *NONNULL_PTR b); + /** * Creates a copy of the RawInvoice */ @@ -17262,6 +17713,13 @@ struct LDKPositiveTimestamp RawDataPart_get_timestamp(const struct LDKRawDataPar */ void RawDataPart_set_timestamp(struct LDKRawDataPart *NONNULL_PTR this_ptr, struct LDKPositiveTimestamp val); +/** + * Checks if two RawDataParts contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool RawDataPart_eq(const struct LDKRawDataPart *NONNULL_PTR a, const struct LDKRawDataPart *NONNULL_PTR b); + /** * Creates a copy of the RawDataPart */ @@ -17272,6 +17730,13 @@ struct LDKRawDataPart RawDataPart_clone(const struct LDKRawDataPart *NONNULL_PTR */ void PositiveTimestamp_free(struct LDKPositiveTimestamp this_obj); +/** + * Checks if two PositiveTimestamps contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool PositiveTimestamp_eq(const struct LDKPositiveTimestamp *NONNULL_PTR a, const struct LDKPositiveTimestamp *NONNULL_PTR b); + /** * Creates a copy of the PositiveTimestamp */ @@ -17282,6 +17747,12 @@ struct LDKPositiveTimestamp PositiveTimestamp_clone(const struct LDKPositiveTime */ enum LDKSiPrefix SiPrefix_clone(const enum LDKSiPrefix *NONNULL_PTR orig); +/** + * Checks if two SiPrefixs contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + */ +bool SiPrefix_eq(const enum LDKSiPrefix *NONNULL_PTR a, const enum LDKSiPrefix *NONNULL_PTR b); + /** * Returns the multiplier to go from a BTC value to picoBTC implied by this SiPrefix. * This is effectively 10^12 * the prefix multiplier @@ -17293,11 +17764,24 @@ MUST_USE_RES uint64_t SiPrefix_multiplier(const enum LDKSiPrefix *NONNULL_PTR th */ enum LDKCurrency Currency_clone(const enum LDKCurrency *NONNULL_PTR orig); +/** + * Checks if two Currencys contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + */ +bool Currency_eq(const enum LDKCurrency *NONNULL_PTR a, const enum LDKCurrency *NONNULL_PTR b); + /** * Frees any resources used by the Sha256, if is_owned is set and inner is non-NULL. */ void Sha256_free(struct LDKSha256 this_obj); +/** + * Checks if two Sha256s contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool Sha256_eq(const struct LDKSha256 *NONNULL_PTR a, const struct LDKSha256 *NONNULL_PTR b); + /** * Creates a copy of the Sha256 */ @@ -17308,6 +17792,13 @@ struct LDKSha256 Sha256_clone(const struct LDKSha256 *NONNULL_PTR orig); */ void Description_free(struct LDKDescription this_obj); +/** + * Checks if two Descriptions contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool Description_eq(const struct LDKDescription *NONNULL_PTR a, const struct LDKDescription *NONNULL_PTR b); + /** * Creates a copy of the Description */ @@ -17318,6 +17809,13 @@ struct LDKDescription Description_clone(const struct LDKDescription *NONNULL_PTR */ void PayeePubKey_free(struct LDKPayeePubKey this_obj); +/** + * Checks if two PayeePubKeys contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool PayeePubKey_eq(const struct LDKPayeePubKey *NONNULL_PTR a, const struct LDKPayeePubKey *NONNULL_PTR b); + /** * Creates a copy of the PayeePubKey */ @@ -17328,6 +17826,13 @@ struct LDKPayeePubKey PayeePubKey_clone(const struct LDKPayeePubKey *NONNULL_PTR */ void ExpiryTime_free(struct LDKExpiryTime this_obj); +/** + * Checks if two ExpiryTimes contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool ExpiryTime_eq(const struct LDKExpiryTime *NONNULL_PTR a, const struct LDKExpiryTime *NONNULL_PTR b); + /** * Creates a copy of the ExpiryTime */ @@ -17338,6 +17843,13 @@ struct LDKExpiryTime ExpiryTime_clone(const struct LDKExpiryTime *NONNULL_PTR or */ void MinFinalCltvExpiry_free(struct LDKMinFinalCltvExpiry this_obj); +/** + * Checks if two MinFinalCltvExpirys contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool MinFinalCltvExpiry_eq(const struct LDKMinFinalCltvExpiry *NONNULL_PTR a, const struct LDKMinFinalCltvExpiry *NONNULL_PTR b); + /** * Creates a copy of the MinFinalCltvExpiry */ @@ -17353,11 +17865,24 @@ void Fallback_free(struct LDKFallback this_ptr); */ struct LDKFallback Fallback_clone(const struct LDKFallback *NONNULL_PTR orig); +/** + * Checks if two Fallbacks contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + */ +bool Fallback_eq(const struct LDKFallback *NONNULL_PTR a, const struct LDKFallback *NONNULL_PTR b); + /** * Frees any resources used by the InvoiceSignature, if is_owned is set and inner is non-NULL. */ void InvoiceSignature_free(struct LDKInvoiceSignature this_obj); +/** + * Checks if two InvoiceSignatures contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool InvoiceSignature_eq(const struct LDKInvoiceSignature *NONNULL_PTR a, const struct LDKInvoiceSignature *NONNULL_PTR b); + /** * Creates a copy of the InvoiceSignature */ @@ -17368,6 +17893,13 @@ struct LDKInvoiceSignature InvoiceSignature_clone(const struct LDKInvoiceSignatu */ void RouteHint_free(struct LDKRouteHint this_obj); +/** + * Checks if two RouteHints contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + * Two objects with NULL inner values will be considered "equal" here. + */ +bool RouteHint_eq(const struct LDKRouteHint *NONNULL_PTR a, const struct LDKRouteHint *NONNULL_PTR b); + /** * Creates a copy of the RouteHint */ @@ -17593,6 +18125,12 @@ MUST_USE_RES struct LDKCVec_RouteHintHopZ RouteHint_into_inner(struct LDKRouteHi */ enum LDKCreationError CreationError_clone(const enum LDKCreationError *NONNULL_PTR orig); +/** + * Checks if two CreationErrors contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + */ +bool CreationError_eq(const enum LDKCreationError *NONNULL_PTR a, const enum LDKCreationError *NONNULL_PTR b); + /** * Get the string representation of a CreationError object */ @@ -17603,6 +18141,12 @@ struct LDKStr CreationError_to_str(const enum LDKCreationError *NONNULL_PTR o); */ enum LDKSemanticError SemanticError_clone(const enum LDKSemanticError *NONNULL_PTR orig); +/** + * Checks if two SemanticErrors contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + */ +bool SemanticError_eq(const enum LDKSemanticError *NONNULL_PTR a, const enum LDKSemanticError *NONNULL_PTR b); + /** * Get the string representation of a SemanticError object */ @@ -17618,6 +18162,12 @@ void SignOrCreationError_free(struct LDKSignOrCreationError this_ptr); */ struct LDKSignOrCreationError SignOrCreationError_clone(const struct LDKSignOrCreationError *NONNULL_PTR orig); +/** + * Checks if two SignOrCreationErrors contain equal inner contents. + * This ignores pointers and is_owned flags and looks at the values in fields. + */ +bool SignOrCreationError_eq(const struct LDKSignOrCreationError *NONNULL_PTR a, const struct LDKSignOrCreationError *NONNULL_PTR b); + /** * Get the string representation of a SignOrCreationError object */ diff --git a/lightning-c-bindings/include/lightningpp.hpp b/lightning-c-bindings/include/lightningpp.hpp index d00d238..3292990 100644 --- a/lightning-c-bindings/include/lightningpp.hpp +++ b/lightning-c-bindings/include/lightningpp.hpp @@ -953,6 +953,21 @@ public: const LDKEventsProvider* operator &() const { return &self; } const LDKEventsProvider* operator ->() const { return &self; } }; +class EventHandler { +private: + LDKEventHandler self; +public: + EventHandler(const EventHandler&) = delete; + EventHandler(EventHandler&& o) : self(o.self) { memset(&o, 0, sizeof(EventHandler)); } + EventHandler(LDKEventHandler&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEventHandler)); } + operator LDKEventHandler() && { LDKEventHandler res = self; memset(&self, 0, sizeof(LDKEventHandler)); return res; } + ~EventHandler() { EventHandler_free(self); } + EventHandler& operator=(EventHandler&& o) { EventHandler_free(self); self = o.self; memset(&o, 0, sizeof(EventHandler)); return *this; } + LDKEventHandler* operator &() { return &self; } + LDKEventHandler* operator ->() { return &self; } + const LDKEventHandler* operator &() const { return &self; } + const LDKEventHandler* operator ->() const { return &self; } +}; class NetworkGraph { private: LDKNetworkGraph self; @@ -2227,6 +2242,21 @@ public: const LDKCResult_TxOutAccessErrorZ* operator &() const { return &self; } const LDKCResult_TxOutAccessErrorZ* operator ->() const { return &self; } }; +class CResult_NetAddressDecodeErrorZ { +private: + LDKCResult_NetAddressDecodeErrorZ self; +public: + CResult_NetAddressDecodeErrorZ(const CResult_NetAddressDecodeErrorZ&) = delete; + CResult_NetAddressDecodeErrorZ(CResult_NetAddressDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_NetAddressDecodeErrorZ)); } + CResult_NetAddressDecodeErrorZ(LDKCResult_NetAddressDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_NetAddressDecodeErrorZ)); } + operator LDKCResult_NetAddressDecodeErrorZ() && { LDKCResult_NetAddressDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_NetAddressDecodeErrorZ)); return res; } + ~CResult_NetAddressDecodeErrorZ() { CResult_NetAddressDecodeErrorZ_free(self); } + CResult_NetAddressDecodeErrorZ& operator=(CResult_NetAddressDecodeErrorZ&& o) { CResult_NetAddressDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_NetAddressDecodeErrorZ)); return *this; } + LDKCResult_NetAddressDecodeErrorZ* operator &() { return &self; } + LDKCResult_NetAddressDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_NetAddressDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_NetAddressDecodeErrorZ* operator ->() const { return &self; } +}; class CResult_UnsignedNodeAnnouncementDecodeErrorZ { private: LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ self; @@ -2257,21 +2287,6 @@ public: const LDKCResult_ReplyChannelRangeDecodeErrorZ* operator &() const { return &self; } const LDKCResult_ReplyChannelRangeDecodeErrorZ* operator ->() const { return &self; } }; -class CResult_GossipTimestampFilterDecodeErrorZ { -private: - LDKCResult_GossipTimestampFilterDecodeErrorZ self; -public: - CResult_GossipTimestampFilterDecodeErrorZ(const CResult_GossipTimestampFilterDecodeErrorZ&) = delete; - CResult_GossipTimestampFilterDecodeErrorZ(CResult_GossipTimestampFilterDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_GossipTimestampFilterDecodeErrorZ)); } - CResult_GossipTimestampFilterDecodeErrorZ(LDKCResult_GossipTimestampFilterDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_GossipTimestampFilterDecodeErrorZ)); } - operator LDKCResult_GossipTimestampFilterDecodeErrorZ() && { LDKCResult_GossipTimestampFilterDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_GossipTimestampFilterDecodeErrorZ)); return res; } - ~CResult_GossipTimestampFilterDecodeErrorZ() { CResult_GossipTimestampFilterDecodeErrorZ_free(self); } - CResult_GossipTimestampFilterDecodeErrorZ& operator=(CResult_GossipTimestampFilterDecodeErrorZ&& o) { CResult_GossipTimestampFilterDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_GossipTimestampFilterDecodeErrorZ)); return *this; } - LDKCResult_GossipTimestampFilterDecodeErrorZ* operator &() { return &self; } - LDKCResult_GossipTimestampFilterDecodeErrorZ* operator ->() { return &self; } - const LDKCResult_GossipTimestampFilterDecodeErrorZ* operator &() const { return &self; } - const LDKCResult_GossipTimestampFilterDecodeErrorZ* operator ->() const { return &self; } -}; class CResult_ChannelReestablishDecodeErrorZ { private: LDKCResult_ChannelReestablishDecodeErrorZ self; @@ -2287,6 +2302,21 @@ public: const LDKCResult_ChannelReestablishDecodeErrorZ* operator &() const { return &self; } const LDKCResult_ChannelReestablishDecodeErrorZ* operator ->() const { return &self; } }; +class CResult_GossipTimestampFilterDecodeErrorZ { +private: + LDKCResult_GossipTimestampFilterDecodeErrorZ self; +public: + CResult_GossipTimestampFilterDecodeErrorZ(const CResult_GossipTimestampFilterDecodeErrorZ&) = delete; + CResult_GossipTimestampFilterDecodeErrorZ(CResult_GossipTimestampFilterDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_GossipTimestampFilterDecodeErrorZ)); } + CResult_GossipTimestampFilterDecodeErrorZ(LDKCResult_GossipTimestampFilterDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_GossipTimestampFilterDecodeErrorZ)); } + operator LDKCResult_GossipTimestampFilterDecodeErrorZ() && { LDKCResult_GossipTimestampFilterDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_GossipTimestampFilterDecodeErrorZ)); return res; } + ~CResult_GossipTimestampFilterDecodeErrorZ() { CResult_GossipTimestampFilterDecodeErrorZ_free(self); } + CResult_GossipTimestampFilterDecodeErrorZ& operator=(CResult_GossipTimestampFilterDecodeErrorZ&& o) { CResult_GossipTimestampFilterDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_GossipTimestampFilterDecodeErrorZ)); return *this; } + LDKCResult_GossipTimestampFilterDecodeErrorZ* operator &() { return &self; } + LDKCResult_GossipTimestampFilterDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_GossipTimestampFilterDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_GossipTimestampFilterDecodeErrorZ* operator ->() const { return &self; } +}; class CResult_InvoiceSignOrCreationErrorZ { private: LDKCResult_InvoiceSignOrCreationErrorZ self; @@ -2362,6 +2392,21 @@ public: const LDKCResult_InitFeaturesDecodeErrorZ* operator &() const { return &self; } const LDKCResult_InitFeaturesDecodeErrorZ* operator ->() const { return &self; } }; +class CResult_StaticPaymentOutputDescriptorDecodeErrorZ { +private: + LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ self; +public: + CResult_StaticPaymentOutputDescriptorDecodeErrorZ(const CResult_StaticPaymentOutputDescriptorDecodeErrorZ&) = delete; + CResult_StaticPaymentOutputDescriptorDecodeErrorZ(CResult_StaticPaymentOutputDescriptorDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_StaticPaymentOutputDescriptorDecodeErrorZ)); } + CResult_StaticPaymentOutputDescriptorDecodeErrorZ(LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ)); } + operator LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ() && { LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ)); return res; } + ~CResult_StaticPaymentOutputDescriptorDecodeErrorZ() { CResult_StaticPaymentOutputDescriptorDecodeErrorZ_free(self); } + CResult_StaticPaymentOutputDescriptorDecodeErrorZ& operator=(CResult_StaticPaymentOutputDescriptorDecodeErrorZ&& o) { CResult_StaticPaymentOutputDescriptorDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_StaticPaymentOutputDescriptorDecodeErrorZ)); return *this; } + LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ* operator &() { return &self; } + LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ* operator ->() const { return &self; } +}; class CResult_CommitmentTransactionDecodeErrorZ { private: LDKCResult_CommitmentTransactionDecodeErrorZ self; @@ -2647,6 +2692,21 @@ public: const LDKCResult_UpdateFeeDecodeErrorZ* operator &() const { return &self; } const LDKCResult_UpdateFeeDecodeErrorZ* operator ->() const { return &self; } }; +class CResult_RouteHopDecodeErrorZ { +private: + LDKCResult_RouteHopDecodeErrorZ self; +public: + CResult_RouteHopDecodeErrorZ(const CResult_RouteHopDecodeErrorZ&) = delete; + CResult_RouteHopDecodeErrorZ(CResult_RouteHopDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_RouteHopDecodeErrorZ)); } + CResult_RouteHopDecodeErrorZ(LDKCResult_RouteHopDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_RouteHopDecodeErrorZ)); } + operator LDKCResult_RouteHopDecodeErrorZ() && { LDKCResult_RouteHopDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_RouteHopDecodeErrorZ)); return res; } + ~CResult_RouteHopDecodeErrorZ() { CResult_RouteHopDecodeErrorZ_free(self); } + CResult_RouteHopDecodeErrorZ& operator=(CResult_RouteHopDecodeErrorZ&& o) { CResult_RouteHopDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_RouteHopDecodeErrorZ)); return *this; } + LDKCResult_RouteHopDecodeErrorZ* operator &() { return &self; } + LDKCResult_RouteHopDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_RouteHopDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_RouteHopDecodeErrorZ* operator ->() const { return &self; } +}; class CVec_ChannelMonitorZ { private: LDKCVec_ChannelMonitorZ self; @@ -3367,6 +3427,21 @@ public: const LDKCVec_u64Z* operator &() const { return &self; } const LDKCVec_u64Z* operator ->() const { return &self; } }; +class CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { +private: + LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ self; +public: + CResult_DelayedPaymentOutputDescriptorDecodeErrorZ(const CResult_DelayedPaymentOutputDescriptorDecodeErrorZ&) = delete; + CResult_DelayedPaymentOutputDescriptorDecodeErrorZ(CResult_DelayedPaymentOutputDescriptorDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_DelayedPaymentOutputDescriptorDecodeErrorZ)); } + CResult_DelayedPaymentOutputDescriptorDecodeErrorZ(LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ)); } + operator LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ() && { LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ)); return res; } + ~CResult_DelayedPaymentOutputDescriptorDecodeErrorZ() { CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_free(self); } + CResult_DelayedPaymentOutputDescriptorDecodeErrorZ& operator=(CResult_DelayedPaymentOutputDescriptorDecodeErrorZ&& o) { CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_DelayedPaymentOutputDescriptorDecodeErrorZ)); return *this; } + LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ* operator &() { return &self; } + LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_DelayedPaymentOutputDescriptorDecodeErrorZ* operator ->() const { return &self; } +}; class CResult_StringErrorZ { private: LDKCResult_StringErrorZ self; diff --git a/lightning-c-bindings/src/c_types/derived.rs b/lightning-c-bindings/src/c_types/derived.rs index fc351bd..08052db 100644 --- a/lightning-c-bindings/src/c_types/derived.rs +++ b/lightning-c-bindings/src/c_types/derived.rs @@ -3574,6 +3574,97 @@ impl From CResult_RouteHopDecodeErrorZ { + CResult_RouteHopDecodeErrorZ { + contents: CResult_RouteHopDecodeErrorZPtr { + result: Box::into_raw(Box::new(o)), + }, + result_ok: true, + } +} +#[no_mangle] +/// Creates a new CResult_RouteHopDecodeErrorZ in the error state. +pub extern "C" fn CResult_RouteHopDecodeErrorZ_err(e: crate::lightning::ln::msgs::DecodeError) -> CResult_RouteHopDecodeErrorZ { + CResult_RouteHopDecodeErrorZ { + contents: CResult_RouteHopDecodeErrorZPtr { + err: Box::into_raw(Box::new(e)), + }, + result_ok: false, + } +} +#[no_mangle] +/// Frees any resources used by the CResult_RouteHopDecodeErrorZ. +pub extern "C" fn CResult_RouteHopDecodeErrorZ_free(_res: CResult_RouteHopDecodeErrorZ) { } +impl Drop for CResult_RouteHopDecodeErrorZ { + fn drop(&mut self) { + if self.result_ok { + if unsafe { !(self.contents.result as *mut ()).is_null() } { + let _ = unsafe { Box::from_raw(self.contents.result) }; + } + } else { + if unsafe { !(self.contents.err as *mut ()).is_null() } { + let _ = unsafe { Box::from_raw(self.contents.err) }; + } + } + } +} +impl From> for CResult_RouteHopDecodeErrorZ { + fn from(mut o: crate::c_types::CResultTempl) -> Self { + let contents = if o.result_ok { + let result = unsafe { o.contents.result }; + unsafe { o.contents.result = std::ptr::null_mut() }; + CResult_RouteHopDecodeErrorZPtr { result } + } else { + let err = unsafe { o.contents.err }; + unsafe { o.contents.err = std::ptr::null_mut(); } + CResult_RouteHopDecodeErrorZPtr { err } + }; + Self { + contents, + result_ok: o.result_ok, + } + } +} +impl Clone for CResult_RouteHopDecodeErrorZ { + fn clone(&self) -> Self { + if self.result_ok { + Self { result_ok: true, contents: CResult_RouteHopDecodeErrorZPtr { + result: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.result }))) + } } + } else { + Self { result_ok: false, contents: CResult_RouteHopDecodeErrorZPtr { + err: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.err }))) + } } + } + } +} +#[no_mangle] +/// Creates a new CResult_RouteHopDecodeErrorZ which has the same data as `orig` +/// but with all dynamically-allocated buffers duplicated in new buffers. +pub extern "C" fn CResult_RouteHopDecodeErrorZ_clone(orig: &CResult_RouteHopDecodeErrorZ) -> CResult_RouteHopDecodeErrorZ { orig.clone() } +#[repr(C)] /// A dynamically-allocated array of crate::lightning::routing::router::RouteHops of arbitrary size. /// This corresponds to std::vector in C++ pub struct CVec_RouteHopZ { @@ -5845,6 +5936,97 @@ impl Clone for CResult_CResult_NetAddressu8ZDecodeErrorZ { /// but with all dynamically-allocated buffers duplicated in new buffers. pub extern "C" fn CResult_CResult_NetAddressu8ZDecodeErrorZ_clone(orig: &CResult_CResult_NetAddressu8ZDecodeErrorZ) -> CResult_CResult_NetAddressu8ZDecodeErrorZ { orig.clone() } #[repr(C)] +/// The contents of CResult_NetAddressDecodeErrorZ +pub union CResult_NetAddressDecodeErrorZPtr { + /// A pointer to the contents in the success state. + /// Reading from this pointer when `result_ok` is not set is undefined. + pub result: *mut crate::lightning::ln::msgs::NetAddress, + /// A pointer to the contents in the error state. + /// Reading from this pointer when `result_ok` is set is undefined. + pub err: *mut crate::lightning::ln::msgs::DecodeError, +} +#[repr(C)] +/// A CResult_NetAddressDecodeErrorZ represents the result of a fallible operation, +/// containing a crate::lightning::ln::msgs::NetAddress on success and a crate::lightning::ln::msgs::DecodeError on failure. +/// `result_ok` indicates the overall state, and the contents are provided via `contents`. +pub struct CResult_NetAddressDecodeErrorZ { + /// The contents of this CResult_NetAddressDecodeErrorZ, accessible via either + /// `err` or `result` depending on the state of `result_ok`. + pub contents: CResult_NetAddressDecodeErrorZPtr, + /// Whether this CResult_NetAddressDecodeErrorZ represents a success state. + pub result_ok: bool, +} +#[no_mangle] +/// Creates a new CResult_NetAddressDecodeErrorZ in the success state. +pub extern "C" fn CResult_NetAddressDecodeErrorZ_ok(o: crate::lightning::ln::msgs::NetAddress) -> CResult_NetAddressDecodeErrorZ { + CResult_NetAddressDecodeErrorZ { + contents: CResult_NetAddressDecodeErrorZPtr { + result: Box::into_raw(Box::new(o)), + }, + result_ok: true, + } +} +#[no_mangle] +/// Creates a new CResult_NetAddressDecodeErrorZ in the error state. +pub extern "C" fn CResult_NetAddressDecodeErrorZ_err(e: crate::lightning::ln::msgs::DecodeError) -> CResult_NetAddressDecodeErrorZ { + CResult_NetAddressDecodeErrorZ { + contents: CResult_NetAddressDecodeErrorZPtr { + err: Box::into_raw(Box::new(e)), + }, + result_ok: false, + } +} +#[no_mangle] +/// Frees any resources used by the CResult_NetAddressDecodeErrorZ. +pub extern "C" fn CResult_NetAddressDecodeErrorZ_free(_res: CResult_NetAddressDecodeErrorZ) { } +impl Drop for CResult_NetAddressDecodeErrorZ { + fn drop(&mut self) { + if self.result_ok { + if unsafe { !(self.contents.result as *mut ()).is_null() } { + let _ = unsafe { Box::from_raw(self.contents.result) }; + } + } else { + if unsafe { !(self.contents.err as *mut ()).is_null() } { + let _ = unsafe { Box::from_raw(self.contents.err) }; + } + } + } +} +impl From> for CResult_NetAddressDecodeErrorZ { + fn from(mut o: crate::c_types::CResultTempl) -> Self { + let contents = if o.result_ok { + let result = unsafe { o.contents.result }; + unsafe { o.contents.result = std::ptr::null_mut() }; + CResult_NetAddressDecodeErrorZPtr { result } + } else { + let err = unsafe { o.contents.err }; + unsafe { o.contents.err = std::ptr::null_mut(); } + CResult_NetAddressDecodeErrorZPtr { err } + }; + Self { + contents, + result_ok: o.result_ok, + } + } +} +impl Clone for CResult_NetAddressDecodeErrorZ { + fn clone(&self) -> Self { + if self.result_ok { + Self { result_ok: true, contents: CResult_NetAddressDecodeErrorZPtr { + result: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.result }))) + } } + } else { + Self { result_ok: false, contents: CResult_NetAddressDecodeErrorZPtr { + err: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.err }))) + } } + } + } +} +#[no_mangle] +/// Creates a new CResult_NetAddressDecodeErrorZ which has the same data as `orig` +/// but with all dynamically-allocated buffers duplicated in new buffers. +pub extern "C" fn CResult_NetAddressDecodeErrorZ_clone(orig: &CResult_NetAddressDecodeErrorZ) -> CResult_NetAddressDecodeErrorZ { orig.clone() } +#[repr(C)] /// A dynamically-allocated array of crate::lightning::ln::msgs::UpdateAddHTLCs of arbitrary size. /// This corresponds to std::vector in C++ pub struct CVec_UpdateAddHTLCZ { @@ -8941,6 +9123,188 @@ impl Clone for CResult_InvoiceSignOrCreationErrorZ { /// but with all dynamically-allocated buffers duplicated in new buffers. pub extern "C" fn CResult_InvoiceSignOrCreationErrorZ_clone(orig: &CResult_InvoiceSignOrCreationErrorZ) -> CResult_InvoiceSignOrCreationErrorZ { orig.clone() } #[repr(C)] +/// The contents of CResult_DelayedPaymentOutputDescriptorDecodeErrorZ +pub union CResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr { + /// A pointer to the contents in the success state. + /// Reading from this pointer when `result_ok` is not set is undefined. + pub result: *mut crate::lightning::chain::keysinterface::DelayedPaymentOutputDescriptor, + /// A pointer to the contents in the error state. + /// Reading from this pointer when `result_ok` is set is undefined. + pub err: *mut crate::lightning::ln::msgs::DecodeError, +} +#[repr(C)] +/// A CResult_DelayedPaymentOutputDescriptorDecodeErrorZ represents the result of a fallible operation, +/// containing a crate::lightning::chain::keysinterface::DelayedPaymentOutputDescriptor on success and a crate::lightning::ln::msgs::DecodeError on failure. +/// `result_ok` indicates the overall state, and the contents are provided via `contents`. +pub struct CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + /// The contents of this CResult_DelayedPaymentOutputDescriptorDecodeErrorZ, accessible via either + /// `err` or `result` depending on the state of `result_ok`. + pub contents: CResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr, + /// Whether this CResult_DelayedPaymentOutputDescriptorDecodeErrorZ represents a success state. + pub result_ok: bool, +} +#[no_mangle] +/// Creates a new CResult_DelayedPaymentOutputDescriptorDecodeErrorZ in the success state. +pub extern "C" fn CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_ok(o: crate::lightning::chain::keysinterface::DelayedPaymentOutputDescriptor) -> CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + contents: CResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr { + result: Box::into_raw(Box::new(o)), + }, + result_ok: true, + } +} +#[no_mangle] +/// Creates a new CResult_DelayedPaymentOutputDescriptorDecodeErrorZ in the error state. +pub extern "C" fn CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_err(e: crate::lightning::ln::msgs::DecodeError) -> CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + contents: CResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr { + err: Box::into_raw(Box::new(e)), + }, + result_ok: false, + } +} +#[no_mangle] +/// Frees any resources used by the CResult_DelayedPaymentOutputDescriptorDecodeErrorZ. +pub extern "C" fn CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_free(_res: CResult_DelayedPaymentOutputDescriptorDecodeErrorZ) { } +impl Drop for CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + fn drop(&mut self) { + if self.result_ok { + if unsafe { !(self.contents.result as *mut ()).is_null() } { + let _ = unsafe { Box::from_raw(self.contents.result) }; + } + } else { + if unsafe { !(self.contents.err as *mut ()).is_null() } { + let _ = unsafe { Box::from_raw(self.contents.err) }; + } + } + } +} +impl From> for CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + fn from(mut o: crate::c_types::CResultTempl) -> Self { + let contents = if o.result_ok { + let result = unsafe { o.contents.result }; + unsafe { o.contents.result = std::ptr::null_mut() }; + CResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr { result } + } else { + let err = unsafe { o.contents.err }; + unsafe { o.contents.err = std::ptr::null_mut(); } + CResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr { err } + }; + Self { + contents, + result_ok: o.result_ok, + } + } +} +impl Clone for CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + fn clone(&self) -> Self { + if self.result_ok { + Self { result_ok: true, contents: CResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr { + result: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.result }))) + } } + } else { + Self { result_ok: false, contents: CResult_DelayedPaymentOutputDescriptorDecodeErrorZPtr { + err: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.err }))) + } } + } + } +} +#[no_mangle] +/// Creates a new CResult_DelayedPaymentOutputDescriptorDecodeErrorZ which has the same data as `orig` +/// but with all dynamically-allocated buffers duplicated in new buffers. +pub extern "C" fn CResult_DelayedPaymentOutputDescriptorDecodeErrorZ_clone(orig: &CResult_DelayedPaymentOutputDescriptorDecodeErrorZ) -> CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { orig.clone() } +#[repr(C)] +/// The contents of CResult_StaticPaymentOutputDescriptorDecodeErrorZ +pub union CResult_StaticPaymentOutputDescriptorDecodeErrorZPtr { + /// A pointer to the contents in the success state. + /// Reading from this pointer when `result_ok` is not set is undefined. + pub result: *mut crate::lightning::chain::keysinterface::StaticPaymentOutputDescriptor, + /// A pointer to the contents in the error state. + /// Reading from this pointer when `result_ok` is set is undefined. + pub err: *mut crate::lightning::ln::msgs::DecodeError, +} +#[repr(C)] +/// A CResult_StaticPaymentOutputDescriptorDecodeErrorZ represents the result of a fallible operation, +/// containing a crate::lightning::chain::keysinterface::StaticPaymentOutputDescriptor on success and a crate::lightning::ln::msgs::DecodeError on failure. +/// `result_ok` indicates the overall state, and the contents are provided via `contents`. +pub struct CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + /// The contents of this CResult_StaticPaymentOutputDescriptorDecodeErrorZ, accessible via either + /// `err` or `result` depending on the state of `result_ok`. + pub contents: CResult_StaticPaymentOutputDescriptorDecodeErrorZPtr, + /// Whether this CResult_StaticPaymentOutputDescriptorDecodeErrorZ represents a success state. + pub result_ok: bool, +} +#[no_mangle] +/// Creates a new CResult_StaticPaymentOutputDescriptorDecodeErrorZ in the success state. +pub extern "C" fn CResult_StaticPaymentOutputDescriptorDecodeErrorZ_ok(o: crate::lightning::chain::keysinterface::StaticPaymentOutputDescriptor) -> CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + contents: CResult_StaticPaymentOutputDescriptorDecodeErrorZPtr { + result: Box::into_raw(Box::new(o)), + }, + result_ok: true, + } +} +#[no_mangle] +/// Creates a new CResult_StaticPaymentOutputDescriptorDecodeErrorZ in the error state. +pub extern "C" fn CResult_StaticPaymentOutputDescriptorDecodeErrorZ_err(e: crate::lightning::ln::msgs::DecodeError) -> CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + contents: CResult_StaticPaymentOutputDescriptorDecodeErrorZPtr { + err: Box::into_raw(Box::new(e)), + }, + result_ok: false, + } +} +#[no_mangle] +/// Frees any resources used by the CResult_StaticPaymentOutputDescriptorDecodeErrorZ. +pub extern "C" fn CResult_StaticPaymentOutputDescriptorDecodeErrorZ_free(_res: CResult_StaticPaymentOutputDescriptorDecodeErrorZ) { } +impl Drop for CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + fn drop(&mut self) { + if self.result_ok { + if unsafe { !(self.contents.result as *mut ()).is_null() } { + let _ = unsafe { Box::from_raw(self.contents.result) }; + } + } else { + if unsafe { !(self.contents.err as *mut ()).is_null() } { + let _ = unsafe { Box::from_raw(self.contents.err) }; + } + } + } +} +impl From> for CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + fn from(mut o: crate::c_types::CResultTempl) -> Self { + let contents = if o.result_ok { + let result = unsafe { o.contents.result }; + unsafe { o.contents.result = std::ptr::null_mut() }; + CResult_StaticPaymentOutputDescriptorDecodeErrorZPtr { result } + } else { + let err = unsafe { o.contents.err }; + unsafe { o.contents.err = std::ptr::null_mut(); } + CResult_StaticPaymentOutputDescriptorDecodeErrorZPtr { err } + }; + Self { + contents, + result_ok: o.result_ok, + } + } +} +impl Clone for CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + fn clone(&self) -> Self { + if self.result_ok { + Self { result_ok: true, contents: CResult_StaticPaymentOutputDescriptorDecodeErrorZPtr { + result: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.result }))) + } } + } else { + Self { result_ok: false, contents: CResult_StaticPaymentOutputDescriptorDecodeErrorZPtr { + err: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.err }))) + } } + } + } +} +#[no_mangle] +/// Creates a new CResult_StaticPaymentOutputDescriptorDecodeErrorZ which has the same data as `orig` +/// but with all dynamically-allocated buffers duplicated in new buffers. +pub extern "C" fn CResult_StaticPaymentOutputDescriptorDecodeErrorZ_clone(orig: &CResult_StaticPaymentOutputDescriptorDecodeErrorZ) -> CResult_StaticPaymentOutputDescriptorDecodeErrorZ { orig.clone() } +#[repr(C)] /// The contents of CResult_SpendableOutputDescriptorDecodeErrorZ pub union CResult_SpendableOutputDescriptorDecodeErrorZPtr { /// A pointer to the contents in the success state. diff --git a/lightning-c-bindings/src/lightning/chain/chainmonitor.rs b/lightning-c-bindings/src/lightning/chain/chainmonitor.rs index 3005c4b..2e65f47 100644 --- a/lightning-c-bindings/src/lightning/chain/chainmonitor.rs +++ b/lightning-c-bindings/src/lightning/chain/chainmonitor.rs @@ -224,14 +224,11 @@ pub extern "C" fn ChainMonitor_as_EventsProvider(this_arg: &ChainMonitor) -> cra crate::lightning::util::events::EventsProvider { this_arg: unsafe { (*this_arg).inner as *mut c_void }, free: None, - get_and_clear_pending_events: ChainMonitor_EventsProvider_get_and_clear_pending_events, + process_pending_events: ChainMonitor_EventsProvider_process_pending_events, } } -#[must_use] -extern "C" fn ChainMonitor_EventsProvider_get_and_clear_pending_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_EventZ { - let mut ret = >::get_and_clear_pending_events(unsafe { &mut *(this_arg as *mut nativeChainMonitor) }, ); - let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::lightning::util::events::Event::native_into(item) }); }; - local_ret.into() +extern "C" fn ChainMonitor_EventsProvider_process_pending_events(this_arg: *const c_void, mut handler: crate::lightning::util::events::EventHandler) { + >::process_pending_events(unsafe { &mut *(this_arg as *mut nativeChainMonitor) }, handler) } diff --git a/lightning-c-bindings/src/lightning/chain/channelmonitor.rs b/lightning-c-bindings/src/lightning/chain/channelmonitor.rs index 6bfd3c3..41b9daa 100644 --- a/lightning-c-bindings/src/lightning/chain/channelmonitor.rs +++ b/lightning-c-bindings/src/lightning/chain/channelmonitor.rs @@ -479,6 +479,11 @@ pub extern "C" fn HTLCUpdate_read(ser: crate::c_types::u8slice) -> crate::c_type let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::chain::channelmonitor::HTLCUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; local_res } +/// Number of blocks we wait on seeing a HTLC output being solved before we fail corresponding inbound +/// HTLCs. This prevents us from failing backwards and then getting a reorg resulting in us losing money. + +#[no_mangle] +pub static ANTI_REORG_DELAY: u32 = lightning::chain::channelmonitor::ANTI_REORG_DELAY; use lightning::chain::channelmonitor::ChannelMonitor as nativeChannelMonitorImport; type nativeChannelMonitor = nativeChannelMonitorImport; diff --git a/lightning-c-bindings/src/lightning/chain/keysinterface.rs b/lightning-c-bindings/src/lightning/chain/keysinterface.rs index c3292d3..64e300e 100644 --- a/lightning-c-bindings/src/lightning/chain/keysinterface.rs +++ b/lightning-c-bindings/src/lightning/chain/keysinterface.rs @@ -173,6 +173,22 @@ pub(crate) extern "C" fn DelayedPaymentOutputDescriptor_clone_void(this_ptr: *co pub extern "C" fn DelayedPaymentOutputDescriptor_clone(orig: &DelayedPaymentOutputDescriptor) -> DelayedPaymentOutputDescriptor { orig.clone() } +#[no_mangle] +/// Serialize the DelayedPaymentOutputDescriptor object into a byte array which can be read by DelayedPaymentOutputDescriptor_read +pub extern "C" fn DelayedPaymentOutputDescriptor_write(obj: &DelayedPaymentOutputDescriptor) -> crate::c_types::derived::CVec_u8Z { + crate::c_types::serialize_obj(unsafe { &*unsafe { &*obj }.inner }) +} +#[no_mangle] +pub(crate) extern "C" fn DelayedPaymentOutputDescriptor_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z { + crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeDelayedPaymentOutputDescriptor) }) +} +#[no_mangle] +/// Read a DelayedPaymentOutputDescriptor from a byte array, created by DelayedPaymentOutputDescriptor_write +pub extern "C" fn DelayedPaymentOutputDescriptor_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_DelayedPaymentOutputDescriptorDecodeErrorZ { + let res = crate::c_types::deserialize_obj(ser); + let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::chain::keysinterface::DelayedPaymentOutputDescriptor { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; + local_res +} use lightning::chain::keysinterface::StaticPaymentOutputDescriptor as nativeStaticPaymentOutputDescriptorImport; type nativeStaticPaymentOutputDescriptor = nativeStaticPaymentOutputDescriptorImport; @@ -291,6 +307,22 @@ pub(crate) extern "C" fn StaticPaymentOutputDescriptor_clone_void(this_ptr: *con pub extern "C" fn StaticPaymentOutputDescriptor_clone(orig: &StaticPaymentOutputDescriptor) -> StaticPaymentOutputDescriptor { orig.clone() } +#[no_mangle] +/// Serialize the StaticPaymentOutputDescriptor object into a byte array which can be read by StaticPaymentOutputDescriptor_read +pub extern "C" fn StaticPaymentOutputDescriptor_write(obj: &StaticPaymentOutputDescriptor) -> crate::c_types::derived::CVec_u8Z { + crate::c_types::serialize_obj(unsafe { &*unsafe { &*obj }.inner }) +} +#[no_mangle] +pub(crate) extern "C" fn StaticPaymentOutputDescriptor_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z { + crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeStaticPaymentOutputDescriptor) }) +} +#[no_mangle] +/// Read a StaticPaymentOutputDescriptor from a byte array, created by StaticPaymentOutputDescriptor_write +pub extern "C" fn StaticPaymentOutputDescriptor_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_StaticPaymentOutputDescriptorDecodeErrorZ { + let res = crate::c_types::deserialize_obj(ser); + let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::chain::keysinterface::StaticPaymentOutputDescriptor { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; + local_res +} /// When on-chain outputs are created by rust-lightning (which our counterparty is not able to /// claim at any point in the future) an event is generated which you must track and be able to /// spend on-chain. The information needed to do this is provided in this enum, including the @@ -530,12 +562,12 @@ pub struct BaseSign { /// May return Err if key derivation fails. Callers, such as ChannelMonitor, will panic in such a case. #[must_use] pub sign_holder_commitment_and_htlcs: extern "C" fn (this_arg: *const c_void, commitment_tx: &crate::lightning::ln::chan_utils::HolderCommitmentTransaction) -> crate::c_types::derived::CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ, - /// Create a signature for the given input in a transaction spending an HTLC or commitment - /// transaction output when our counterparty broadcasts an old state. + /// Create a signature for the given input in a transaction spending an HTLC transaction output + /// or a commitment transaction `to_local` output when our counterparty broadcasts an old state. /// - /// A justice transaction may claim multiples outputs at the same time if timelocks are + /// A justice transaction may claim multiple outputs at the same time if timelocks are /// similar, but only a signature for the input at index `input` should be signed for here. - /// It may be called multiples time for same output(s) if a fee-bump is needed with regards + /// It may be called multiple times for same output(s) if a fee-bump is needed with regards /// to an upcoming timelock expiration. /// /// Amount is value of the output spent by this input, committed to in the BIP 143 signature. @@ -544,12 +576,27 @@ pub struct BaseSign { /// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does /// not allow the spending of any funds by itself (you need our holder revocation_secret to do /// so). + #[must_use] + pub sign_justice_revoked_output: extern "C" fn (this_arg: *const c_void, justice_tx: crate::c_types::Transaction, input: usize, amount: u64, per_commitment_key: *const [u8; 32]) -> crate::c_types::derived::CResult_SignatureNoneZ, + /// Create a signature for the given input in a transaction spending a commitment transaction + /// HTLC output when our counterparty broadcasts an old state. /// - /// htlc holds HTLC elements (hash, timelock) if the output being spent is a HTLC output, thus - /// changing the format of the witness script (which is committed to in the BIP 143 - /// signatures). + /// A justice transaction may claim multiple outputs at the same time if timelocks are + /// similar, but only a signature for the input at index `input` should be signed for here. + /// It may be called multiple times for same output(s) if a fee-bump is needed with regards + /// to an upcoming timelock expiration. + /// + /// Amount is value of the output spent by this input, committed to in the BIP 143 signature. + /// + /// per_commitment_key is revocation secret which was provided by our counterparty when they + /// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does + /// not allow the spending of any funds by itself (you need our holder revocation_secret to do + /// so). + /// + /// htlc holds HTLC elements (hash, timelock), thus changing the format of the witness script + /// (which is committed to in the BIP 143 signatures). #[must_use] - pub sign_justice_transaction: extern "C" fn (this_arg: *const c_void, justice_tx: crate::c_types::Transaction, input: usize, amount: u64, per_commitment_key: *const [u8; 32], htlc: &crate::lightning::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ, + pub sign_justice_revoked_htlc: extern "C" fn (this_arg: *const c_void, justice_tx: crate::c_types::Transaction, input: usize, amount: u64, per_commitment_key: *const [u8; 32], htlc: &crate::lightning::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ, /// Create a signature for a claiming transaction for a HTLC output on a counterparty's commitment /// transaction, either offered or received. /// @@ -629,9 +676,13 @@ impl rustBaseSign for BaseSign { let mut local_ret = match ret.result_ok { true => Ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).to_rust(); let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.into_rust().drain(..) { local_orig_ret_0_1.push( { item.into_rust() }); }; let mut local_ret_0 = (orig_ret_0_0.into_rust(), local_orig_ret_0_1); local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })}; local_ret } - fn sign_justice_transaction(&self, mut justice_tx: &bitcoin::blockdata::transaction::Transaction, mut input: usize, mut amount: u64, mut per_commitment_key: &bitcoin::secp256k1::key::SecretKey, mut htlc: &Option, mut _secp_ctx: &bitcoin::secp256k1::Secp256k1) -> Result { - let mut local_htlc = &crate::lightning::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (if htlc.is_none() { std::ptr::null() } else { { (htlc.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false }; - let mut ret = (self.sign_justice_transaction)(self.this_arg, crate::c_types::Transaction::from_bitcoin(justice_tx), input, amount, per_commitment_key.as_ref(), local_htlc); + fn sign_justice_revoked_output(&self, mut justice_tx: &bitcoin::blockdata::transaction::Transaction, mut input: usize, mut amount: u64, mut per_commitment_key: &bitcoin::secp256k1::key::SecretKey, mut _secp_ctx: &bitcoin::secp256k1::Secp256k1) -> Result { + let mut ret = (self.sign_justice_revoked_output)(self.this_arg, crate::c_types::Transaction::from_bitcoin(justice_tx), input, amount, per_commitment_key.as_ref()); + let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })}; + local_ret + } + fn sign_justice_revoked_htlc(&self, mut justice_tx: &bitcoin::blockdata::transaction::Transaction, mut input: usize, mut amount: u64, mut per_commitment_key: &bitcoin::secp256k1::key::SecretKey, mut htlc: &lightning::ln::chan_utils::HTLCOutputInCommitment, mut _secp_ctx: &bitcoin::secp256k1::Secp256k1) -> Result { + let mut ret = (self.sign_justice_revoked_htlc)(self.this_arg, crate::c_types::Transaction::from_bitcoin(justice_tx), input, amount, per_commitment_key.as_ref(), &crate::lightning::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (htlc as *const _) as *mut _ }, is_owned: false }); let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })}; local_ret } @@ -727,9 +778,13 @@ impl lightning::chain::keysinterface::BaseSign for Sign { let mut local_ret = match ret.result_ok { true => Ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).to_rust(); let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.into_rust().drain(..) { local_orig_ret_0_1.push( { item.into_rust() }); }; let mut local_ret_0 = (orig_ret_0_0.into_rust(), local_orig_ret_0_1); local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })}; local_ret } - fn sign_justice_transaction(&self, mut justice_tx: &bitcoin::blockdata::transaction::Transaction, mut input: usize, mut amount: u64, mut per_commitment_key: &bitcoin::secp256k1::key::SecretKey, mut htlc: &Option, mut _secp_ctx: &bitcoin::secp256k1::Secp256k1) -> Result { - let mut local_htlc = &crate::lightning::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (if htlc.is_none() { std::ptr::null() } else { { (htlc.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false }; - let mut ret = (self.BaseSign.sign_justice_transaction)(self.this_arg, crate::c_types::Transaction::from_bitcoin(justice_tx), input, amount, per_commitment_key.as_ref(), local_htlc); + fn sign_justice_revoked_output(&self, mut justice_tx: &bitcoin::blockdata::transaction::Transaction, mut input: usize, mut amount: u64, mut per_commitment_key: &bitcoin::secp256k1::key::SecretKey, mut _secp_ctx: &bitcoin::secp256k1::Secp256k1) -> Result { + let mut ret = (self.BaseSign.sign_justice_revoked_output)(self.this_arg, crate::c_types::Transaction::from_bitcoin(justice_tx), input, amount, per_commitment_key.as_ref()); + let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })}; + local_ret + } + fn sign_justice_revoked_htlc(&self, mut justice_tx: &bitcoin::blockdata::transaction::Transaction, mut input: usize, mut amount: u64, mut per_commitment_key: &bitcoin::secp256k1::key::SecretKey, mut htlc: &lightning::ln::chan_utils::HTLCOutputInCommitment, mut _secp_ctx: &bitcoin::secp256k1::Secp256k1) -> Result { + let mut ret = (self.BaseSign.sign_justice_revoked_htlc)(self.this_arg, crate::c_types::Transaction::from_bitcoin(justice_tx), input, amount, per_commitment_key.as_ref(), &crate::lightning::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (htlc as *const _) as *mut _ }, is_owned: false }); let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })}; local_ret } @@ -1162,7 +1217,8 @@ pub extern "C" fn InMemorySigner_as_BaseSign(this_arg: &InMemorySigner) -> crate channel_keys_id: InMemorySigner_BaseSign_channel_keys_id, sign_counterparty_commitment: InMemorySigner_BaseSign_sign_counterparty_commitment, sign_holder_commitment_and_htlcs: InMemorySigner_BaseSign_sign_holder_commitment_and_htlcs, - sign_justice_transaction: InMemorySigner_BaseSign_sign_justice_transaction, + sign_justice_revoked_output: InMemorySigner_BaseSign_sign_justice_revoked_output, + sign_justice_revoked_htlc: InMemorySigner_BaseSign_sign_justice_revoked_htlc, sign_counterparty_htlc_transaction: InMemorySigner_BaseSign_sign_counterparty_htlc_transaction, sign_closing_transaction: InMemorySigner_BaseSign_sign_closing_transaction, sign_channel_announcement: InMemorySigner_BaseSign_sign_channel_announcement, @@ -1210,9 +1266,14 @@ extern "C" fn InMemorySigner_BaseSign_sign_holder_commitment_and_htlcs(this_arg: local_ret } #[must_use] -extern "C" fn InMemorySigner_BaseSign_sign_justice_transaction(this_arg: *const c_void, mut justice_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, per_commitment_key: *const [u8; 32], htlc: &crate::lightning::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ { - let mut local_htlc = if htlc.inner.is_null() { None } else { Some((* { unsafe { &*htlc.inner } }).clone()) }; - let mut ret = >::sign_justice_transaction(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &justice_tx.into_bitcoin(), input, amount, &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *per_commitment_key}[..]).unwrap(), &local_htlc, secp256k1::SECP256K1); +extern "C" fn InMemorySigner_BaseSign_sign_justice_revoked_output(this_arg: *const c_void, mut justice_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, per_commitment_key: *const [u8; 32]) -> crate::c_types::derived::CResult_SignatureNoneZ { + let mut ret = >::sign_justice_revoked_output(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &justice_tx.into_bitcoin(), input, amount, &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *per_commitment_key}[..]).unwrap(), secp256k1::SECP256K1); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { () /*e*/ }).into() }; + local_ret +} +#[must_use] +extern "C" fn InMemorySigner_BaseSign_sign_justice_revoked_htlc(this_arg: *const c_void, mut justice_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, per_commitment_key: *const [u8; 32], htlc: &crate::lightning::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ { + let mut ret = >::sign_justice_revoked_htlc(unsafe { &mut *(this_arg as *mut nativeInMemorySigner) }, &justice_tx.into_bitcoin(), input, amount, &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *per_commitment_key}[..]).unwrap(), unsafe { &*htlc.inner }, secp256k1::SECP256K1); let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { () /*e*/ }).into() }; local_ret } @@ -1266,7 +1327,8 @@ pub extern "C" fn InMemorySigner_as_Sign(this_arg: &InMemorySigner) -> crate::li channel_keys_id: InMemorySigner_BaseSign_channel_keys_id, sign_counterparty_commitment: InMemorySigner_BaseSign_sign_counterparty_commitment, sign_holder_commitment_and_htlcs: InMemorySigner_BaseSign_sign_holder_commitment_and_htlcs, - sign_justice_transaction: InMemorySigner_BaseSign_sign_justice_transaction, + sign_justice_revoked_output: InMemorySigner_BaseSign_sign_justice_revoked_output, + sign_justice_revoked_htlc: InMemorySigner_BaseSign_sign_justice_revoked_htlc, sign_counterparty_htlc_transaction: InMemorySigner_BaseSign_sign_counterparty_htlc_transaction, sign_closing_transaction: InMemorySigner_BaseSign_sign_closing_transaction, sign_channel_announcement: InMemorySigner_BaseSign_sign_channel_announcement, @@ -1290,7 +1352,8 @@ extern "C" fn InMemorySigner_BaseSign_clone(orig: &crate::lightning::chain::keys channel_keys_id: InMemorySigner_BaseSign_channel_keys_id, sign_counterparty_commitment: InMemorySigner_BaseSign_sign_counterparty_commitment, sign_holder_commitment_and_htlcs: InMemorySigner_BaseSign_sign_holder_commitment_and_htlcs, - sign_justice_transaction: InMemorySigner_BaseSign_sign_justice_transaction, + sign_justice_revoked_output: InMemorySigner_BaseSign_sign_justice_revoked_output, + sign_justice_revoked_htlc: InMemorySigner_BaseSign_sign_justice_revoked_htlc, sign_counterparty_htlc_transaction: InMemorySigner_BaseSign_sign_counterparty_htlc_transaction, sign_closing_transaction: InMemorySigner_BaseSign_sign_closing_transaction, sign_channel_announcement: InMemorySigner_BaseSign_sign_channel_announcement, diff --git a/lightning-c-bindings/src/lightning/chain/mod.rs b/lightning-c-bindings/src/lightning/chain/mod.rs index 2d43823..1f0e019 100644 --- a/lightning-c-bindings/src/lightning/chain/mod.rs +++ b/lightning-c-bindings/src/lightning/chain/mod.rs @@ -18,6 +18,22 @@ pub mod chainmonitor; pub mod channelmonitor; pub mod transaction; pub mod keysinterface; +mod onchaintx { + +use std::str::FromStr; +use std::ffi::c_void; +use bitcoin::hashes::Hash; +use crate::c_types::*; + +} +mod package { + +use std::str::FromStr; +use std::ffi::c_void; +use bitcoin::hashes::Hash; +use crate::c_types::*; + +} /// An error when accessing the chain via [`Access`]. #[must_use] #[derive(Clone)] diff --git a/lightning-c-bindings/src/lightning/chain/transaction.rs b/lightning-c-bindings/src/lightning/chain/transaction.rs index 05667fd..45794a1 100644 --- a/lightning-c-bindings/src/lightning/chain/transaction.rs +++ b/lightning-c-bindings/src/lightning/chain/transaction.rs @@ -111,6 +111,25 @@ pub(crate) extern "C" fn OutPoint_clone_void(this_ptr: *const c_void) -> *mut c_ pub extern "C" fn OutPoint_clone(orig: &OutPoint) -> OutPoint { orig.clone() } +/// Checks if two OutPoints contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn OutPoint_eq(a: &OutPoint, b: &OutPoint) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} +/// Checks if two OutPoints contain equal inner contents. +#[no_mangle] +pub extern "C" fn OutPoint_hash(o: &OutPoint) -> u64 { + if o.inner.is_null() { return 0; } + // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core + #[allow(deprecated)] + let mut hasher = core::hash::SipHasher::new(); + std::hash::Hash::hash(unsafe { &*o.inner }, &mut hasher); + std::hash::Hasher::finish(&hasher) +} /// Convert an `OutPoint` to a lightning channel id. #[must_use] #[no_mangle] diff --git a/lightning-c-bindings/src/lightning/ln/channelmanager.rs b/lightning-c-bindings/src/lightning/ln/channelmanager.rs index d404b81..9b46a8c 100644 --- a/lightning-c-bindings/src/lightning/ln/channelmanager.rs +++ b/lightning-c-bindings/src/lightning/ln/channelmanager.rs @@ -292,7 +292,7 @@ pub extern "C" fn BestBlock_height(this_arg: &BestBlock) -> u32 { #[no_mangle] pub static BREAKDOWN_TIMEOUT: u16 = lightning::ln::channelmanager::BREAKDOWN_TIMEOUT; /// The minimum number of blocks between an inbound HTLC's CLTV and the corresponding outbound -/// HTLC's CLTV. The current default represents roughly six hours of blocks at six blocks/hour. +/// HTLC's CLTV. The current default represents roughly seven hours of blocks at six blocks/hour. /// /// This can be increased (but not decreased) through [`ChannelConfig::cltv_expiry_delta`] /// @@ -368,6 +368,27 @@ pub extern "C" fn ChannelDetails_get_channel_id(this_ptr: &ChannelDetails) -> *c pub extern "C" fn ChannelDetails_set_channel_id(this_ptr: &mut ChannelDetails, mut val: crate::c_types::ThirtyTwoBytes) { unsafe { &mut *this_ptr.inner }.channel_id = val.data; } +/// The Channel's funding transaction output, if we've negotiated the funding transaction with +/// our counterparty already. +/// +/// Note that, if this has been set, `channel_id` will be equivalent to +/// `funding_txo.unwrap().to_channel_id()`. +#[no_mangle] +pub extern "C" fn ChannelDetails_get_funding_txo(this_ptr: &ChannelDetails) -> crate::lightning::chain::transaction::OutPoint { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.funding_txo; + let mut local_inner_val = crate::lightning::chain::transaction::OutPoint { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false }; + local_inner_val +} +/// The Channel's funding transaction output, if we've negotiated the funding transaction with +/// our counterparty already. +/// +/// Note that, if this has been set, `channel_id` will be equivalent to +/// `funding_txo.unwrap().to_channel_id()`. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_funding_txo(this_ptr: &mut ChannelDetails, mut val: crate::lightning::chain::transaction::OutPoint) { + let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_inner()) } }) }; + unsafe { &mut *this_ptr.inner }.funding_txo = local_val; +} /// The position of the funding transaction in the chain. None if the funding transaction has /// not yet been confirmed and the channel fully opened. #[no_mangle] @@ -467,18 +488,63 @@ pub extern "C" fn ChannelDetails_get_inbound_capacity_msat(this_ptr: &ChannelDet pub extern "C" fn ChannelDetails_set_inbound_capacity_msat(this_ptr: &mut ChannelDetails, mut val: u64) { unsafe { &mut *this_ptr.inner }.inbound_capacity_msat = val; } +/// True if the channel was initiated (and thus funded) by us. +#[no_mangle] +pub extern "C" fn ChannelDetails_get_is_outbound(this_ptr: &ChannelDetails) -> bool { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_outbound; + *inner_val +} +/// True if the channel was initiated (and thus funded) by us. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_is_outbound(this_ptr: &mut ChannelDetails, mut val: bool) { + unsafe { &mut *this_ptr.inner }.is_outbound = val; +} +/// True if the channel is confirmed, funding_locked messages have been exchanged, and the +/// channel is not currently being shut down. `funding_locked` message exchange implies the +/// required confirmation count has been reached (and we were connected to the peer at some +/// point after the funding transaction received enough confirmations). +#[no_mangle] +pub extern "C" fn ChannelDetails_get_is_funding_locked(this_ptr: &ChannelDetails) -> bool { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_funding_locked; + *inner_val +} +/// True if the channel is confirmed, funding_locked messages have been exchanged, and the +/// channel is not currently being shut down. `funding_locked` message exchange implies the +/// required confirmation count has been reached (and we were connected to the peer at some +/// point after the funding transaction received enough confirmations). +#[no_mangle] +pub extern "C" fn ChannelDetails_set_is_funding_locked(this_ptr: &mut ChannelDetails, mut val: bool) { + unsafe { &mut *this_ptr.inner }.is_funding_locked = val; +} /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b) -/// the peer is connected, and (c) no monitor update failure is pending resolution. +/// the peer is connected, (c) no monitor update failure is pending resolution, and (d) the +/// channel is not currently negotiating a shutdown. +/// +/// This is a strict superset of `is_funding_locked`. #[no_mangle] -pub extern "C" fn ChannelDetails_get_is_live(this_ptr: &ChannelDetails) -> bool { - let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_live; +pub extern "C" fn ChannelDetails_get_is_usable(this_ptr: &ChannelDetails) -> bool { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_usable; *inner_val } /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b) -/// the peer is connected, and (c) no monitor update failure is pending resolution. +/// the peer is connected, (c) no monitor update failure is pending resolution, and (d) the +/// channel is not currently negotiating a shutdown. +/// +/// This is a strict superset of `is_funding_locked`. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_is_usable(this_ptr: &mut ChannelDetails, mut val: bool) { + unsafe { &mut *this_ptr.inner }.is_usable = val; +} +/// True if this channel is (or will be) publicly-announced. #[no_mangle] -pub extern "C" fn ChannelDetails_set_is_live(this_ptr: &mut ChannelDetails, mut val: bool) { - unsafe { &mut *this_ptr.inner }.is_live = val; +pub extern "C" fn ChannelDetails_get_is_public(this_ptr: &ChannelDetails) -> bool { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_public; + *inner_val +} +/// True if this channel is (or will be) publicly-announced. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_is_public(this_ptr: &mut ChannelDetails, mut val: bool) { + unsafe { &mut *this_ptr.inner }.is_public = val; } impl Clone for ChannelDetails { fn clone(&self) -> Self { @@ -729,8 +795,9 @@ pub extern "C" fn ChannelManager_list_channels(this_arg: &ChannelManager) -> cra /// Gets the list of usable channels, in random order. Useful as an argument to /// get_route to ensure non-announced channels are used. /// -/// These are guaranteed to have their is_live value set to true, see the documentation for -/// ChannelDetails::is_live for more info on exactly what the criteria are. +/// These are guaranteed to have their [`ChannelDetails::is_usable`] value set to true, see the +/// documentation for [`ChannelDetails::is_usable`] for more info on exactly what the criteria +/// are. #[must_use] #[no_mangle] pub extern "C" fn ChannelManager_list_usable_channels(this_arg: &ChannelManager) -> crate::c_types::derived::CVec_ChannelDetailsZ { @@ -835,6 +902,8 @@ pub extern "C" fn ChannelManager_send_payment(this_arg: &ChannelManager, route: /// Note that this includes RBF or similar transaction replacement strategies - lightning does /// not currently support replacing a funding transaction on an existing channel. Instead, /// create a new channel with a conflicting funding transaction. +/// +/// [`Event::FundingGenerationReady`]: crate::util::events::Event::FundingGenerationReady #[must_use] #[no_mangle] pub extern "C" fn ChannelManager_funding_transaction_generated(this_arg: &ChannelManager, temporary_channel_id: *const [u8; 32], mut funding_transaction: crate::c_types::Transaction) -> crate::c_types::derived::CResult_NoneAPIErrorZ { @@ -843,19 +912,24 @@ pub extern "C" fn ChannelManager_funding_transaction_generated(this_arg: &Channe local_ret } -/// Generates a signed node_announcement from the given arguments and creates a -/// BroadcastNodeAnnouncement event. Note that such messages will be ignored unless peers have -/// seen a channel_announcement from us (ie unless we have public channels open). +/// Regenerates channel_announcements and generates a signed node_announcement from the given +/// arguments, providing them in corresponding events via +/// [`get_and_clear_pending_msg_events`], if at least one public channel has been confirmed +/// on-chain. This effectively re-broadcasts all channel announcements and sends our node +/// announcement to ensure that the lightning P2P network is aware of the channels we have and +/// our network addresses. /// -/// RGB is a node \"color\" and alias is a printable human-readable string to describe this node -/// to humans. They carry no in-protocol meaning. +/// `rgb` is a node \"color\" and `alias` is a printable human-readable string to describe this +/// node to humans. They carry no in-protocol meaning. /// -/// addresses represent the set (possibly empty) of socket addresses on which this node accepts -/// incoming connections. These will be broadcast to the network, publicly tying these -/// addresses together. If you wish to preserve user privacy, addresses should likely contain -/// only Tor Onion addresses. +/// `addresses` represent the set (possibly empty) of socket addresses on which this node +/// accepts incoming connections. These will be included in the node_announcement, publicly +/// tying these addresses together and to this node. If you wish to preserve user privacy, +/// addresses should likely contain only Tor Onion addresses. /// -/// Panics if addresses is absurdly large (more than 500). +/// Panics if `addresses` is absurdly large (more than 500). +/// +/// [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events #[no_mangle] pub extern "C" fn ChannelManager_broadcast_node_announcement(this_arg: &ChannelManager, mut rgb: crate::c_types::ThreeBytes, mut alias: crate::c_types::ThirtyTwoBytes, mut addresses: crate::c_types::derived::CVec_NetAddressZ) { let mut local_addresses = Vec::new(); for mut item in addresses.into_rust().drain(..) { local_addresses.push( { item.into_native() }); }; @@ -997,7 +1071,7 @@ pub extern "C" fn ChannelManager_create_inbound_payment(this_arg: &ChannelManage /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for /// in excess of the current time. This should roughly match the expiry time set in the invoice. /// After this many seconds, we will remove the inbound payment, resulting in any attempts to -/// pay the invoice failing. The BOLT spec suggests 7,200 secs as a default validity time for +/// pay the invoice failing. The BOLT spec suggests 3,600 secs as a default validity time for /// invoices when no timeout is set. /// /// Note that we use block header time to time-out pending inbound payments (with some margin @@ -1072,15 +1146,12 @@ pub extern "C" fn ChannelManager_as_EventsProvider(this_arg: &ChannelManager) -> crate::lightning::util::events::EventsProvider { this_arg: unsafe { (*this_arg).inner as *mut c_void }, free: None, - get_and_clear_pending_events: ChannelManager_EventsProvider_get_and_clear_pending_events, + process_pending_events: ChannelManager_EventsProvider_process_pending_events, } } -#[must_use] -extern "C" fn ChannelManager_EventsProvider_get_and_clear_pending_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_EventZ { - let mut ret = >::get_and_clear_pending_events(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, ); - let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::lightning::util::events::Event::native_into(item) }); }; - local_ret.into() +extern "C" fn ChannelManager_EventsProvider_process_pending_events(this_arg: *const c_void, mut handler: crate::lightning::util::events::EventHandler) { + >::process_pending_events(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, handler) } impl From for crate::lightning::chain::Listen { diff --git a/lightning-c-bindings/src/lightning/ln/features.rs b/lightning-c-bindings/src/lightning/ln/features.rs index 52e06db..8a61a85 100644 --- a/lightning-c-bindings/src/lightning/ln/features.rs +++ b/lightning-c-bindings/src/lightning/ln/features.rs @@ -33,6 +33,42 @@ use std::ffi::c_void; use bitcoin::hashes::Hash; use crate::c_types::*; +} +/// Checks if two InitFeaturess contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn InitFeatures_eq(a: &InitFeatures, b: &InitFeatures) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} +/// Checks if two NodeFeaturess contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn NodeFeatures_eq(a: &NodeFeatures, b: &NodeFeatures) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} +/// Checks if two ChannelFeaturess contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn ChannelFeatures_eq(a: &ChannelFeatures, b: &ChannelFeatures) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} +/// Checks if two InvoiceFeaturess contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn InvoiceFeatures_eq(a: &InvoiceFeatures, b: &InvoiceFeatures) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } } impl Clone for InitFeatures { fn clone(&self) -> Self { @@ -354,6 +390,30 @@ pub extern "C" fn InvoiceFeatures_known() -> InvoiceFeatures { InvoiceFeatures { inner: Box::into_raw(Box::new(ret)), is_owned: true } } +/// Returns whether the `payment_secret` feature is supported. +#[must_use] +#[no_mangle] +pub extern "C" fn InitFeatures_supports_payment_secret(this_arg: &InitFeatures) -> bool { + let mut ret = unsafe { &*this_arg.inner }.supports_payment_secret(); + ret +} + +/// Returns whether the `payment_secret` feature is supported. +#[must_use] +#[no_mangle] +pub extern "C" fn NodeFeatures_supports_payment_secret(this_arg: &NodeFeatures) -> bool { + let mut ret = unsafe { &*this_arg.inner }.supports_payment_secret(); + ret +} + +/// Returns whether the `payment_secret` feature is supported. +#[must_use] +#[no_mangle] +pub extern "C" fn InvoiceFeatures_supports_payment_secret(this_arg: &InvoiceFeatures) -> bool { + let mut ret = unsafe { &*this_arg.inner }.supports_payment_secret(); + ret +} + #[no_mangle] /// Serialize the InitFeatures object into a byte array which can be read by InitFeatures_read pub extern "C" fn InitFeatures_write(obj: &InitFeatures) -> crate::c_types::derived::CVec_u8Z { diff --git a/lightning-c-bindings/src/lightning/ln/mod.rs b/lightning-c-bindings/src/lightning/ln/mod.rs index 1061f9b..abc0e0e 100644 --- a/lightning-c-bindings/src/lightning/ln/mod.rs +++ b/lightning-c-bindings/src/lightning/ln/mod.rs @@ -27,14 +27,6 @@ pub mod msgs; pub mod peer_handler; pub mod chan_utils; pub mod features; -mod onchaintx { - -use std::str::FromStr; -use std::ffi::c_void; -use bitcoin::hashes::Hash; -use crate::c_types::*; - -} mod peer_channel_encryptor { use std::str::FromStr; diff --git a/lightning-c-bindings/src/lightning/ln/msgs.rs b/lightning-c-bindings/src/lightning/ln/msgs.rs index d8906ea..0bdb9fa 100644 --- a/lightning-c-bindings/src/lightning/ln/msgs.rs +++ b/lightning-c-bindings/src/lightning/ln/msgs.rs @@ -2688,6 +2688,13 @@ pub extern "C" fn Result_read(ser: crate::c_types::u8slice) -> crate::c_types::d let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { let mut local_res_0 = match o { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::ln::msgs::NetAddress::native_into(o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { e }).into() }; local_res_0 }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; local_res } +#[no_mangle] +/// Read a NetAddress from a byte array, created by NetAddress_write +pub extern "C" fn NetAddress_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_NetAddressDecodeErrorZ { + let res = crate::c_types::deserialize_obj(ser); + let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::ln::msgs::NetAddress::native_into(o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; + local_res +} use lightning::ln::msgs::UnsignedNodeAnnouncement as nativeUnsignedNodeAnnouncementImport; type nativeUnsignedNodeAnnouncement = nativeUnsignedNodeAnnouncementImport; diff --git a/lightning-c-bindings/src/lightning/mod.rs b/lightning-c-bindings/src/lightning/mod.rs index e473d63..ddbcbb7 100644 --- a/lightning-c-bindings/src/lightning/mod.rs +++ b/lightning-c-bindings/src/lightning/mod.rs @@ -25,3 +25,11 @@ pub mod util; pub mod chain; pub mod ln; pub mod routing; +mod prelude { + +use std::str::FromStr; +use std::ffi::c_void; +use bitcoin::hashes::Hash; +use crate::c_types::*; + +} diff --git a/lightning-c-bindings/src/lightning/routing/network_graph.rs b/lightning-c-bindings/src/lightning/routing/network_graph.rs index 0d50980..7ce133a 100644 --- a/lightning-c-bindings/src/lightning/routing/network_graph.rs +++ b/lightning-c-bindings/src/lightning/routing/network_graph.rs @@ -804,6 +804,15 @@ pub extern "C" fn RoutingFees_new(mut base_msat_arg: u32, mut proportional_milli proportional_millionths: proportional_millionths_arg, })), is_owned: true } } +/// Checks if two RoutingFeess contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn RoutingFees_eq(a: &RoutingFees, b: &RoutingFees) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for RoutingFees { fn clone(&self) -> Self { Self { @@ -824,13 +833,6 @@ pub extern "C" fn RoutingFees_clone(orig: &RoutingFees) -> RoutingFees { orig.clone() } #[no_mangle] -/// Read a RoutingFees from a byte array, created by RoutingFees_write -pub extern "C" fn RoutingFees_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_RoutingFeesDecodeErrorZ { - let res = crate::c_types::deserialize_obj(ser); - let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::routing::network_graph::RoutingFees { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; - local_res -} -#[no_mangle] /// Serialize the RoutingFees object into a byte array which can be read by RoutingFees_read pub extern "C" fn RoutingFees_write(obj: &RoutingFees) -> crate::c_types::derived::CVec_u8Z { crate::c_types::serialize_obj(unsafe { &*unsafe { &*obj }.inner }) @@ -839,6 +841,13 @@ pub extern "C" fn RoutingFees_write(obj: &RoutingFees) -> crate::c_types::derive pub(crate) extern "C" fn RoutingFees_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z { crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeRoutingFees) }) } +#[no_mangle] +/// Read a RoutingFees from a byte array, created by RoutingFees_write +pub extern "C" fn RoutingFees_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_RoutingFeesDecodeErrorZ { + let res = crate::c_types::deserialize_obj(ser); + let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::routing::network_graph::RoutingFees { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; + local_res +} use lightning::routing::network_graph::NodeAnnouncementInfo as nativeNodeAnnouncementInfoImport; type nativeNodeAnnouncementInfo = nativeNodeAnnouncementInfoImport; diff --git a/lightning-c-bindings/src/lightning/routing/router.rs b/lightning-c-bindings/src/lightning/routing/router.rs index 9479bc9..5ee9614 100644 --- a/lightning-c-bindings/src/lightning/routing/router.rs +++ b/lightning-c-bindings/src/lightning/routing/router.rs @@ -169,6 +169,22 @@ pub(crate) extern "C" fn RouteHop_clone_void(this_ptr: *const c_void) -> *mut c_ pub extern "C" fn RouteHop_clone(orig: &RouteHop) -> RouteHop { orig.clone() } +#[no_mangle] +/// Serialize the RouteHop object into a byte array which can be read by RouteHop_read +pub extern "C" fn RouteHop_write(obj: &RouteHop) -> crate::c_types::derived::CVec_u8Z { + crate::c_types::serialize_obj(unsafe { &*unsafe { &*obj }.inner }) +} +#[no_mangle] +pub(crate) extern "C" fn RouteHop_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z { + crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeRouteHop) }) +} +#[no_mangle] +/// Read a RouteHop from a byte array, created by RouteHop_write +pub extern "C" fn RouteHop_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_RouteHopDecodeErrorZ { + let res = crate::c_types::deserialize_obj(ser); + let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::routing::router::RouteHop { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; + local_res +} use lightning::routing::router::Route as nativeRouteImport; type nativeRoute = nativeRouteImport; @@ -400,6 +416,15 @@ pub extern "C" fn RouteHintHop_new(mut src_node_id_arg: crate::c_types::PublicKe htlc_maximum_msat: local_htlc_maximum_msat_arg, })), is_owned: true } } +/// Checks if two RouteHintHops contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn RouteHintHop_eq(a: &RouteHintHop, b: &RouteHintHop) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for RouteHintHop { fn clone(&self) -> Self { Self { diff --git a/lightning-c-bindings/src/lightning/util/config.rs b/lightning-c-bindings/src/lightning/util/config.rs index cc58f69..63def43 100644 --- a/lightning-c-bindings/src/lightning/util/config.rs +++ b/lightning-c-bindings/src/lightning/util/config.rs @@ -319,52 +319,6 @@ pub extern "C" fn ChannelHandshakeLimits_get_min_max_accepted_htlcs(this_ptr: &C pub extern "C" fn ChannelHandshakeLimits_set_min_max_accepted_htlcs(this_ptr: &mut ChannelHandshakeLimits, mut val: u16) { unsafe { &mut *this_ptr.inner }.min_max_accepted_htlcs = val; } -/// Outputs below a certain value will not be added to on-chain transactions. The dust value is -/// required to always be higher than this value so this only applies to HTLC outputs (and -/// potentially to-self outputs before any payments have been made). -/// Thus, HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. -/// This setting allows you to set a minimum dust limit for their commitment transactions, -/// reflecting the reality that tiny outputs are not considered standard transactions and will -/// not propagate through the Bitcoin network. -/// -/// Default value: 546, the current dust limit on the Bitcoin network. -#[no_mangle] -pub extern "C" fn ChannelHandshakeLimits_get_min_dust_limit_satoshis(this_ptr: &ChannelHandshakeLimits) -> u64 { - let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.min_dust_limit_satoshis; - *inner_val -} -/// Outputs below a certain value will not be added to on-chain transactions. The dust value is -/// required to always be higher than this value so this only applies to HTLC outputs (and -/// potentially to-self outputs before any payments have been made). -/// Thus, HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. -/// This setting allows you to set a minimum dust limit for their commitment transactions, -/// reflecting the reality that tiny outputs are not considered standard transactions and will -/// not propagate through the Bitcoin network. -/// -/// Default value: 546, the current dust limit on the Bitcoin network. -#[no_mangle] -pub extern "C" fn ChannelHandshakeLimits_set_min_dust_limit_satoshis(this_ptr: &mut ChannelHandshakeLimits, mut val: u64) { - unsafe { &mut *this_ptr.inner }.min_dust_limit_satoshis = val; -} -/// Maximum allowed threshold above which outputs will not be generated in their commitment -/// transactions. -/// HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. -/// -/// Default value: u64::max_value. -#[no_mangle] -pub extern "C" fn ChannelHandshakeLimits_get_max_dust_limit_satoshis(this_ptr: &ChannelHandshakeLimits) -> u64 { - let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.max_dust_limit_satoshis; - *inner_val -} -/// Maximum allowed threshold above which outputs will not be generated in their commitment -/// transactions. -/// HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. -/// -/// Default value: u64::max_value. -#[no_mangle] -pub extern "C" fn ChannelHandshakeLimits_set_max_dust_limit_satoshis(this_ptr: &mut ChannelHandshakeLimits, mut val: u64) { - unsafe { &mut *this_ptr.inner }.max_dust_limit_satoshis = val; -} /// Before a channel is usable the funding transaction will need to be confirmed by at least a /// certain number of blocks, specified by the node which is not the funder (as the funder can /// assume they aren't going to double-spend themselves). @@ -431,15 +385,13 @@ pub extern "C" fn ChannelHandshakeLimits_set_their_to_self_delay(this_ptr: &mut /// Constructs a new ChannelHandshakeLimits given each field #[must_use] #[no_mangle] -pub extern "C" fn ChannelHandshakeLimits_new(mut min_funding_satoshis_arg: u64, mut max_htlc_minimum_msat_arg: u64, mut min_max_htlc_value_in_flight_msat_arg: u64, mut max_channel_reserve_satoshis_arg: u64, mut min_max_accepted_htlcs_arg: u16, mut min_dust_limit_satoshis_arg: u64, mut max_dust_limit_satoshis_arg: u64, mut max_minimum_depth_arg: u32, mut force_announced_channel_preference_arg: bool, mut their_to_self_delay_arg: u16) -> ChannelHandshakeLimits { +pub extern "C" fn ChannelHandshakeLimits_new(mut min_funding_satoshis_arg: u64, mut max_htlc_minimum_msat_arg: u64, mut min_max_htlc_value_in_flight_msat_arg: u64, mut max_channel_reserve_satoshis_arg: u64, mut min_max_accepted_htlcs_arg: u16, mut max_minimum_depth_arg: u32, mut force_announced_channel_preference_arg: bool, mut their_to_self_delay_arg: u16) -> ChannelHandshakeLimits { ChannelHandshakeLimits { inner: Box::into_raw(Box::new(nativeChannelHandshakeLimits { min_funding_satoshis: min_funding_satoshis_arg, max_htlc_minimum_msat: max_htlc_minimum_msat_arg, min_max_htlc_value_in_flight_msat: min_max_htlc_value_in_flight_msat_arg, max_channel_reserve_satoshis: max_channel_reserve_satoshis_arg, min_max_accepted_htlcs: min_max_accepted_htlcs_arg, - min_dust_limit_satoshis: min_dust_limit_satoshis_arg, - max_dust_limit_satoshis: max_dust_limit_satoshis_arg, max_minimum_depth: max_minimum_depth_arg, force_announced_channel_preference: force_announced_channel_preference_arg, their_to_self_delay: their_to_self_delay_arg, diff --git a/lightning-c-bindings/src/lightning/util/events.rs b/lightning-c-bindings/src/lightning/util/events.rs index 43c4db3..2aea6ac 100644 --- a/lightning-c-bindings/src/lightning/util/events.rs +++ b/lightning-c-bindings/src/lightning/util/events.rs @@ -90,8 +90,6 @@ pub enum Event { }, /// Indicates an outbound payment we made succeeded (ie it made it all the way to its target /// and we got back the payment preimage for it). - /// Note that duplicative PaymentSent Events may be generated - it is your responsibility to - /// deduplicate them by payment_preimage (which MUST be unique)! PaymentSent { /// The preimage to the hash given to ChannelManager::send_payment. /// Note that this serves as a payment receipt, if you wish to have such a thing, you must @@ -100,8 +98,6 @@ pub enum Event { }, /// Indicates an outbound payment we made failed. Probably some intermediary node dropped /// something. You may wish to retry with a different route. - /// Note that duplicative PaymentFailed Events may be generated - it is your responsibility to - /// deduplicate them by payment_hash (which MUST be unique)! PaymentFailed { /// The hash which was given to ChannelManager::send_payment. payment_hash: crate::c_types::ThirtyTwoBytes, @@ -1087,33 +1083,82 @@ impl Drop for MessageSendEventsProvider { } } } -/// A trait indicating an object may generate events +/// A trait indicating an object may generate events. +/// +/// Events are processed by passing an [`EventHandler`] to [`process_pending_events`]. +/// +/// # Requirements +/// +/// See [`process_pending_events`] for requirements around event processing. +/// +/// When using this trait, [`process_pending_events`] will call [`handle_event`] for each pending +/// event since the last invocation. The handler must either act upon the event immediately +/// or preserve it for later handling. +/// +/// Note, handlers may call back into the provider and thus deadlocking must be avoided. Be sure to +/// consult the provider's documentation on the implication of processing events and how a handler +/// may safely use the provider (e.g., see [`ChannelManager::process_pending_events`] and +/// [`ChainMonitor::process_pending_events`]). +/// +/// (C-not implementable) As there is likely no reason for a user to implement this trait on their +/// own type(s). +/// +/// [`process_pending_events`]: Self::process_pending_events +/// [`handle_event`]: EventHandler::handle_event +/// [`ChannelManager::process_pending_events`]: crate::ln::channelmanager::ChannelManager#method.process_pending_events +/// [`ChainMonitor::process_pending_events`]: crate::chain::chainmonitor::ChainMonitor#method.process_pending_events #[repr(C)] pub struct EventsProvider { /// An opaque pointer which is passed to your function implementations as an argument. /// This has no meaning in the LDK, and can be NULL or any other value. pub this_arg: *mut c_void, - /// Gets the list of pending events which were generated by previous actions, clearing the list - /// in the process. - #[must_use] - pub get_and_clear_pending_events: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_EventZ, + /// Processes any events generated since the last call using the given event handler. + /// + /// Subsequent calls must only process new events. However, handlers must be capable of handling + /// duplicate events across process restarts. This may occur if the provider was recovered from + /// an old state (i.e., it hadn't been successfully persisted after processing pending events). + pub process_pending_events: extern "C" fn (this_arg: *const c_void, handler: crate::lightning::util::events::EventHandler), /// Frees any resources associated with this object given its this_arg pointer. /// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed. pub free: Option, } use lightning::util::events::EventsProvider as rustEventsProvider; -impl rustEventsProvider for EventsProvider { - fn get_and_clear_pending_events(&self) -> Vec { - let mut ret = (self.get_and_clear_pending_events)(self.this_arg); - let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { item.into_native() }); }; - local_ret +/// Calls the free function if one is set +#[no_mangle] +pub extern "C" fn EventsProvider_free(this_ptr: EventsProvider) { } +impl Drop for EventsProvider { + fn drop(&mut self) { + if let Some(f) = self.free { + f(self.this_arg); + } + } +} +/// A trait implemented for objects handling events from [`EventsProvider`]. +#[repr(C)] +pub struct EventHandler { + /// An opaque pointer which is passed to your function implementations as an argument. + /// This has no meaning in the LDK, and can be NULL or any other value. + pub this_arg: *mut c_void, + /// Handles the given [`Event`]. + /// + /// See [`EventsProvider`] for details that must be considered when implementing this method. + pub handle_event: extern "C" fn (this_arg: *const c_void, event: crate::lightning::util::events::Event), + /// Frees any resources associated with this object given its this_arg pointer. + /// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed. + pub free: Option, +} + +use lightning::util::events::EventHandler as rustEventHandler; +impl rustEventHandler for EventHandler { + fn handle_event(&self, mut event: lightning::util::events::Event) { + (self.handle_event)(self.this_arg, crate::lightning::util::events::Event::native_into(event)) } } // 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 EventsProvider { +impl std::ops::Deref for EventHandler { type Target = Self; fn deref(&self) -> &Self { self @@ -1121,8 +1166,8 @@ impl std::ops::Deref for EventsProvider { } /// Calls the free function if one is set #[no_mangle] -pub extern "C" fn EventsProvider_free(this_ptr: EventsProvider) { } -impl Drop for EventsProvider { +pub extern "C" fn EventHandler_free(this_ptr: EventHandler) { } +impl Drop for EventHandler { fn drop(&mut self) { if let Some(f) = self.free { f(self.this_arg); diff --git a/lightning-c-bindings/src/lightning/util/logger.rs b/lightning-c-bindings/src/lightning/util/logger.rs index 0373245..eddadf6 100644 --- a/lightning-c-bindings/src/lightning/util/logger.rs +++ b/lightning-c-bindings/src/lightning/util/logger.rs @@ -88,6 +88,21 @@ impl Level { pub extern "C" fn Level_clone(orig: &Level) -> Level { orig.clone() } +/// Checks if two Levels contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn Level_eq(a: &Level, b: &Level) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } +} +/// Checks if two Levels contain equal inner contents. +#[no_mangle] +pub extern "C" fn Level_hash(o: &Level) -> u64 { + // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core + #[allow(deprecated)] + let mut hasher = core::hash::SipHasher::new(); + std::hash::Hash::hash(&o.to_native(), &mut hasher); + std::hash::Hasher::finish(&hasher) +} /// Returns the most verbose logging level. #[must_use] #[no_mangle] diff --git a/lightning-c-bindings/src/lightning/util/mod.rs b/lightning-c-bindings/src/lightning/util/mod.rs index eb3f2a2..8a9e9df 100644 --- a/lightning-c-bindings/src/lightning/util/mod.rs +++ b/lightning-c-bindings/src/lightning/util/mod.rs @@ -26,6 +26,14 @@ use std::ffi::c_void; use bitcoin::hashes::Hash; use crate::c_types::*; +} +mod ser_macros { + +use std::str::FromStr; +use std::ffi::c_void; +use bitcoin::hashes::Hash; +use crate::c_types::*; + } mod byte_utils { @@ -98,14 +106,6 @@ use std::ffi::c_void; use bitcoin::hashes::Hash; use crate::c_types::*; -} -mod ser_macros { - -use std::str::FromStr; -use std::ffi::c_void; -use bitcoin::hashes::Hash; -use crate::c_types::*; - } mod macro_logger { diff --git a/lightning-c-bindings/src/lightning_invoice/mod.rs b/lightning-c-bindings/src/lightning_invoice/mod.rs index 0895be3..f8db6ef 100644 --- a/lightning-c-bindings/src/lightning_invoice/mod.rs +++ b/lightning-c-bindings/src/lightning_invoice/mod.rs @@ -178,6 +178,15 @@ impl Invoice { ret } } +/// Checks if two Invoices contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn Invoice_eq(a: &Invoice, b: &Invoice) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for Invoice { fn clone(&self) -> Self { Self { @@ -246,6 +255,15 @@ impl SignedRawInvoice { ret } } +/// Checks if two SignedRawInvoices contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn SignedRawInvoice_eq(a: &SignedRawInvoice, b: &SignedRawInvoice) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for SignedRawInvoice { fn clone(&self) -> Self { Self { @@ -325,6 +343,15 @@ pub extern "C" fn RawInvoice_get_data(this_ptr: &RawInvoice) -> crate::lightning pub extern "C" fn RawInvoice_set_data(this_ptr: &mut RawInvoice, mut val: crate::lightning_invoice::RawDataPart) { unsafe { &mut *this_ptr.inner }.data = *unsafe { Box::from_raw(val.take_inner()) }; } +/// Checks if two RawInvoices contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn RawInvoice_eq(a: &RawInvoice, b: &RawInvoice) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for RawInvoice { fn clone(&self) -> Self { Self { @@ -400,6 +427,15 @@ pub extern "C" fn RawDataPart_get_timestamp(this_ptr: &RawDataPart) -> crate::li pub extern "C" fn RawDataPart_set_timestamp(this_ptr: &mut RawDataPart, mut val: crate::lightning_invoice::PositiveTimestamp) { unsafe { &mut *this_ptr.inner }.timestamp = *unsafe { Box::from_raw(val.take_inner()) }; } +/// Checks if two RawDataParts contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn RawDataPart_eq(a: &RawDataPart, b: &RawDataPart) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for RawDataPart { fn clone(&self) -> Self { Self { @@ -469,6 +505,15 @@ impl PositiveTimestamp { ret } } +/// Checks if two PositiveTimestamps contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn PositiveTimestamp_eq(a: &PositiveTimestamp, b: &PositiveTimestamp) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for PositiveTimestamp { fn clone(&self) -> Self { Self { @@ -546,6 +591,12 @@ impl SiPrefix { pub extern "C" fn SiPrefix_clone(orig: &SiPrefix) -> SiPrefix { orig.clone() } +/// Checks if two SiPrefixs contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn SiPrefix_eq(a: &SiPrefix, b: &SiPrefix) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } +} /// Returns the multiplier to go from a BTC value to picoBTC implied by this SiPrefix. /// This is effectively 10^12 * the prefix multiplier #[must_use] @@ -613,6 +664,12 @@ impl Currency { pub extern "C" fn Currency_clone(orig: &Currency) -> Currency { orig.clone() } +/// Checks if two Currencys contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn Currency_eq(a: &Currency, b: &Currency) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } +} use lightning_invoice::Sha256 as nativeSha256Import; type nativeSha256 = nativeSha256Import; @@ -658,6 +715,15 @@ impl Sha256 { ret } } +/// Checks if two Sha256s contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn Sha256_eq(a: &Sha256, b: &Sha256) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for Sha256 { fn clone(&self) -> Self { Self { @@ -725,6 +791,15 @@ impl Description { ret } } +/// Checks if two Descriptions contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn Description_eq(a: &Description, b: &Description) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for Description { fn clone(&self) -> Self { Self { @@ -789,6 +864,15 @@ impl PayeePubKey { ret } } +/// Checks if two PayeePubKeys contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn PayeePubKey_eq(a: &PayeePubKey, b: &PayeePubKey) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for PayeePubKey { fn clone(&self) -> Self { Self { @@ -859,6 +943,15 @@ impl ExpiryTime { ret } } +/// Checks if two ExpiryTimes contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn ExpiryTime_eq(a: &ExpiryTime, b: &ExpiryTime) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for ExpiryTime { fn clone(&self) -> Self { Self { @@ -923,6 +1016,15 @@ impl MinFinalCltvExpiry { ret } } +/// Checks if two MinFinalCltvExpirys contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn MinFinalCltvExpiry_eq(a: &MinFinalCltvExpiry, b: &MinFinalCltvExpiry) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for MinFinalCltvExpiry { fn clone(&self) -> Self { Self { @@ -1061,6 +1163,12 @@ pub extern "C" fn Fallback_free(this_ptr: Fallback) { } pub extern "C" fn Fallback_clone(orig: &Fallback) -> Fallback { orig.clone() } +/// Checks if two Fallbacks contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn Fallback_eq(a: &Fallback, b: &Fallback) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } +} use lightning_invoice::InvoiceSignature as nativeInvoiceSignatureImport; type nativeInvoiceSignature = nativeInvoiceSignatureImport; @@ -1106,6 +1214,15 @@ impl InvoiceSignature { ret } } +/// Checks if two InvoiceSignatures contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn InvoiceSignature_eq(a: &InvoiceSignature, b: &InvoiceSignature) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for InvoiceSignature { fn clone(&self) -> Self { Self { @@ -1174,6 +1291,15 @@ impl RouteHint { ret } } +/// Checks if two RouteHints contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +/// Two objects with NULL inner values will be considered "equal" here. +#[no_mangle] +pub extern "C" fn RouteHint_eq(a: &RouteHint, b: &RouteHint) -> bool { + if a.inner == b.inner { return true; } + if a.inner.is_null() || b.inner.is_null() { return false; } + if unsafe { &*a.inner } == unsafe { &*b.inner } { true } else { false } +} impl Clone for RouteHint { fn clone(&self) -> Self { Self { @@ -1647,6 +1773,12 @@ impl CreationError { pub extern "C" fn CreationError_clone(orig: &CreationError) -> CreationError { orig.clone() } +/// Checks if two CreationErrors contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn CreationError_eq(a: &CreationError, b: &CreationError) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } +} #[no_mangle] /// Get the string representation of a CreationError object pub extern "C" fn CreationError_to_str(o: &crate::lightning_invoice::CreationError) -> Str { @@ -1666,6 +1798,10 @@ pub enum SemanticError { NoDescription, /// The invoice contains multiple descriptions and/or description hashes which isn't allowed MultipleDescriptions, + /// The invoice contains multiple payment secrets + MultiplePaymentSecrets, + /// The invoice's features are invalid + InvalidFeatures, /// The recovery id doesn't fit the signature/pub key InvalidRecoveryId, /// The invoice's signature is invalid @@ -1680,6 +1816,8 @@ impl SemanticError { SemanticError::MultiplePaymentHashes => nativeSemanticError::MultiplePaymentHashes, SemanticError::NoDescription => nativeSemanticError::NoDescription, SemanticError::MultipleDescriptions => nativeSemanticError::MultipleDescriptions, + SemanticError::MultiplePaymentSecrets => nativeSemanticError::MultiplePaymentSecrets, + SemanticError::InvalidFeatures => nativeSemanticError::InvalidFeatures, SemanticError::InvalidRecoveryId => nativeSemanticError::InvalidRecoveryId, SemanticError::InvalidSignature => nativeSemanticError::InvalidSignature, } @@ -1691,6 +1829,8 @@ impl SemanticError { SemanticError::MultiplePaymentHashes => nativeSemanticError::MultiplePaymentHashes, SemanticError::NoDescription => nativeSemanticError::NoDescription, SemanticError::MultipleDescriptions => nativeSemanticError::MultipleDescriptions, + SemanticError::MultiplePaymentSecrets => nativeSemanticError::MultiplePaymentSecrets, + SemanticError::InvalidFeatures => nativeSemanticError::InvalidFeatures, SemanticError::InvalidRecoveryId => nativeSemanticError::InvalidRecoveryId, SemanticError::InvalidSignature => nativeSemanticError::InvalidSignature, } @@ -1702,6 +1842,8 @@ impl SemanticError { nativeSemanticError::MultiplePaymentHashes => SemanticError::MultiplePaymentHashes, nativeSemanticError::NoDescription => SemanticError::NoDescription, nativeSemanticError::MultipleDescriptions => SemanticError::MultipleDescriptions, + nativeSemanticError::MultiplePaymentSecrets => SemanticError::MultiplePaymentSecrets, + nativeSemanticError::InvalidFeatures => SemanticError::InvalidFeatures, nativeSemanticError::InvalidRecoveryId => SemanticError::InvalidRecoveryId, nativeSemanticError::InvalidSignature => SemanticError::InvalidSignature, } @@ -1713,6 +1855,8 @@ impl SemanticError { nativeSemanticError::MultiplePaymentHashes => SemanticError::MultiplePaymentHashes, nativeSemanticError::NoDescription => SemanticError::NoDescription, nativeSemanticError::MultipleDescriptions => SemanticError::MultipleDescriptions, + nativeSemanticError::MultiplePaymentSecrets => SemanticError::MultiplePaymentSecrets, + nativeSemanticError::InvalidFeatures => SemanticError::InvalidFeatures, nativeSemanticError::InvalidRecoveryId => SemanticError::InvalidRecoveryId, nativeSemanticError::InvalidSignature => SemanticError::InvalidSignature, } @@ -1723,6 +1867,12 @@ impl SemanticError { pub extern "C" fn SemanticError_clone(orig: &SemanticError) -> SemanticError { orig.clone() } +/// Checks if two SemanticErrors contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn SemanticError_eq(a: &SemanticError, b: &SemanticError) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } +} #[no_mangle] /// Get the string representation of a SemanticError object pub extern "C" fn SemanticError_to_str(o: &crate::lightning_invoice::SemanticError) -> Str { @@ -1806,6 +1956,12 @@ pub extern "C" fn SignOrCreationError_free(this_ptr: SignOrCreationError) { } pub extern "C" fn SignOrCreationError_clone(orig: &SignOrCreationError) -> SignOrCreationError { orig.clone() } +/// Checks if two SignOrCreationErrors contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn SignOrCreationError_eq(a: &SignOrCreationError, b: &SignOrCreationError) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } +} #[no_mangle] /// Get the string representation of a SignOrCreationError object pub extern "C" fn SignOrCreationError_to_str(o: &crate::lightning_invoice::SignOrCreationError) -> Str {