From: Matt Corallo <649246+TheBlueMatt@users.noreply.github.com> Date: Wed, 23 Mar 2022 03:14:55 +0000 (+0000) Subject: Merge pull request #62 from TheBlueMatt/main X-Git-Tag: v0.0.105.2~1 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-c-bindings;a=commitdiff_plain;h=eb231dca2c899c983d212bcceab5dacef4e0c1e0;hp=11cd55b6baf2c94a44f0cd24774f0d822ff90d66 Merge pull request #62 from TheBlueMatt/main Expose ProbabilisticScorer in Bindings --- diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 647f344..fbe3c99 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -111,9 +111,12 @@ fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path if let syn::GenericArgument::Type(args_ty) = args.args.iter().next().unwrap() { types.write_c_type(w, args_ty, Some(generics), false); - assert!(!types.write_from_c_conversion_new_var(&mut arg_conv, &format_ident!("arg"), &args_ty, Some(generics))); + write!(&mut arg_conv, "\t").unwrap(); + if types.write_from_c_conversion_new_var(&mut arg_conv, &format_ident!("arg"), &args_ty, Some(generics)) { + write!(&mut arg_conv, "\n\t").unwrap(); + } - write!(&mut arg_conv, "\tlet arg_conv = ").unwrap(); + write!(&mut arg_conv, "let arg_conv = ").unwrap(); types.write_from_c_conversion_prefix(&mut arg_conv, &args_ty, Some(generics)); write!(&mut arg_conv, "arg").unwrap(); types.write_from_c_conversion_suffix(&mut arg_conv, &args_ty, Some(generics)); @@ -1324,7 +1327,14 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ } } else if let Some(resolved_path) = types.maybe_resolve_ident(&ident) { if let Some(aliases) = types.crate_types.reverse_alias_map.get(&resolved_path).cloned() { + let mut gen_types = Some(GenericTypes::new(Some(resolved_path.clone()))); + if !gen_types.as_mut().unwrap().learn_generics(&i.generics, types) { + gen_types = None; + } 'alias_impls: for (alias, arguments) in aliases { + let mut new_ty_generics = Vec::new(); + let mut need_generics = false; + let alias_resolved = types.resolve_path(&alias, None); for (idx, gen) in i.generics.params.iter().enumerate() { match gen { @@ -1334,17 +1344,26 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ if let syn::PathArguments::AngleBracketed(ref t) = &arguments { assert!(idx < t.args.len()); if let syn::GenericArgument::Type(syn::Type::Path(p)) = &t.args[idx] { - let generic_arg = types.resolve_path(&p.path, None); - let generic_bound = types.resolve_path(&trait_bound.path, None); - if let Some(traits_impld) = types.crate_types.trait_impls.get(&generic_arg) { - for trait_impld in traits_impld { - if *trait_impld == generic_bound { continue 'bounds_check; } + if let Some(generic_arg) = types.maybe_resolve_path(&p.path, None) { + + new_ty_generics.push((type_param.ident.clone(), syn::Type::Path(p.clone()))); + let generic_bound = types.resolve_path(&trait_bound.path, None); + if let Some(traits_impld) = types.crate_types.trait_impls.get(&generic_arg) { + for trait_impld in traits_impld { + if *trait_impld == generic_bound { continue 'bounds_check; } + } + eprintln!("struct {}'s generic arg {} didn't match bound {}", alias_resolved, generic_arg, generic_bound); + continue 'alias_impls; + } else { + eprintln!("struct {}'s generic arg {} didn't match bound {}", alias_resolved, generic_arg, generic_bound); + continue 'alias_impls; } - eprintln!("struct {}'s generic arg {} didn't match bound {}", alias_resolved, generic_arg, generic_bound); - continue 'alias_impls; + } else if gen_types.is_some() { + new_ty_generics.push((type_param.ident.clone(), + gen_types.as_ref().resolve_type(&syn::Type::Path(p.clone())).clone())); + need_generics = true; } else { - eprintln!("struct {}'s generic arg {} didn't match bound {}", alias_resolved, generic_arg, generic_bound); - continue 'alias_impls; + unimplemented!(); } } else { unimplemented!(); } } else { unimplemented!(); } @@ -1355,19 +1374,54 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ syn::GenericParam::Const(_) => unimplemented!(), } } + let mut params = syn::punctuated::Punctuated::new(); + let real_aliased = + if need_generics { + let alias_generics = types.crate_types.opaques.get(&alias_resolved).unwrap().1; + + // If we need generics on the alias, create impl generic bounds... + assert_eq!(new_ty_generics.len(), i.generics.params.len()); + let mut args = syn::punctuated::Punctuated::new(); + for (ident, param) in new_ty_generics.drain(..) { + // TODO: We blindly assume that generics in the type alias and + // the aliased type have the same names, which we really shouldn't. + if alias_generics.params.iter().any(|generic| + if let syn::GenericParam::Type(t) = generic { t.ident == ident } else { false }) + { + args.push(parse_quote!(#ident)); + } + params.push(syn::GenericParam::Type(syn::TypeParam { + attrs: Vec::new(), + ident, + colon_token: None, + bounds: syn::punctuated::Punctuated::new(), + eq_token: Some(syn::token::Eq(Span::call_site())), + default: Some(param), + })); + } + // ... and swap the last segment of the impl self_ty to use the generic bounds. + let mut res = alias.clone(); + res.segments.last_mut().unwrap().arguments = syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { + colon2_token: None, + lt_token: syn::token::Lt(Span::call_site()), + args, + gt_token: syn::token::Gt(Span::call_site()), + }); + res + } else { alias.clone() }; let aliased_impl = syn::ItemImpl { attrs: i.attrs.clone(), brace_token: syn::token::Brace(Span::call_site()), defaultness: None, generics: syn::Generics { lt_token: None, - params: syn::punctuated::Punctuated::new(), + params, gt_token: None, where_clause: None, }, impl_token: syn::Token![impl](Span::call_site()), items: i.items.clone(), - self_ty: Box::new(syn::Type::Path(syn::TypePath { qself: None, path: alias.clone() })), + self_ty: Box::new(syn::Type::Path(syn::TypePath { qself: None, path: real_aliased })), trait_: i.trait_.clone(), unsafety: None, }; @@ -1812,17 +1866,33 @@ fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &CrateTypes<'a> ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } - let mut process_alias = true; - for tok in t.generics.params.iter() { - if let syn::GenericParam::Lifetime(_) = tok {} - else { process_alias = false; } - } - if process_alias { - match &*t.ty { - syn::Type::Path(_) => - writeln_opaque(&mut out, &t.ident, &format!("{}", t.ident), &t.generics, &t.attrs, &type_resolver, header_file, cpp_header_file), - _ => {} - } + match &*t.ty { + syn::Type::Path(p) => { + let real_ty = type_resolver.resolve_path(&p.path, None); + let real_generic_bounds = type_resolver.crate_types.opaques.get(&real_ty).map(|t| t.1).or( + type_resolver.crate_types.priv_structs.get(&real_ty).map(|r| *r)).unwrap(); + let mut resolved_generics = t.generics.clone(); + + if let syn::PathArguments::AngleBracketed(real_generics) = &p.path.segments.last().unwrap().arguments { + for (real_idx, real_param) in real_generics.args.iter().enumerate() { + if let syn::GenericArgument::Type(syn::Type::Path(real_param_path)) = real_param { + for param in resolved_generics.params.iter_mut() { + if let syn::GenericParam::Type(type_param) = param { + if Some(&type_param.ident) == real_param_path.path.get_ident() { + if let syn::GenericParam::Type(real_type_param) = &real_generic_bounds.params[real_idx] { + type_param.bounds = real_type_param.bounds.clone(); + type_param.default = real_type_param.default.clone(); + + } + } + } + } + } + } + } + + writeln_opaque(&mut out, &t.ident, &format!("{}", t.ident), &resolved_generics, &t.attrs, &type_resolver, header_file, cpp_header_file)}, + _ => {} } } }, @@ -1878,12 +1948,15 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a match item { syn::Item::Struct(s) => { if let syn::Visibility::Public(_) = s.vis { + let struct_path = format!("{}::{}", module, s.ident); match export_status(&s.attrs) { ExportStatus::Export => {}, - ExportStatus::NoExport|ExportStatus::TestOnly => continue, + ExportStatus::NoExport|ExportStatus::TestOnly => { + crate_types.priv_structs.insert(struct_path, &s.generics); + 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, &s.generics)); } }, @@ -1911,29 +1984,22 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"), } let type_path = format!("{}::{}", module, t.ident); - let mut process_alias = true; - for tok in t.generics.params.iter() { - if let syn::GenericParam::Lifetime(_) = tok {} - else { process_alias = false; } - } - if process_alias { - match &*t.ty { - syn::Type::Path(p) => { - let t_ident = &t.ident; - - // If its a path with no generics, assume we don't map the aliased type and map it opaque - let path_obj = parse_quote!(#t_ident); - let args_obj = p.path.segments.last().unwrap().arguments.clone(); - match crate_types.reverse_alias_map.entry(import_resolver.maybe_resolve_path(&p.path, None).unwrap()) { - hash_map::Entry::Occupied(mut e) => { e.get_mut().push((path_obj, args_obj)); }, - hash_map::Entry::Vacant(e) => { e.insert(vec![(path_obj, args_obj)]); }, - } - - crate_types.opaques.insert(type_path, (t_ident, &t.generics)); - }, - _ => { - crate_types.type_aliases.insert(type_path, import_resolver.resolve_imported_refs((*t.ty).clone())); + match &*t.ty { + syn::Type::Path(p) => { + let t_ident = &t.ident; + + // If its a path with no generics, assume we don't map the aliased type and map it opaque + let path_obj = parse_quote!(#t_ident); + let args_obj = p.path.segments.last().unwrap().arguments.clone(); + match crate_types.reverse_alias_map.entry(import_resolver.maybe_resolve_path(&p.path, None).unwrap()) { + hash_map::Entry::Occupied(mut e) => { e.get_mut().push((path_obj, args_obj)); }, + hash_map::Entry::Vacant(e) => { e.insert(vec![(path_obj, args_obj)]); }, } + + crate_types.opaques.insert(type_path, (t_ident, &t.generics)); + }, + _ => { + crate_types.type_aliases.insert(type_path, import_resolver.resolve_imported_refs((*t.ty).clone())); } } } diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 346f588..2efba6e 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -352,7 +352,7 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { } } -trait ResolveType<'a> { fn resolve_type(&'a self, ty: &'a syn::Type) -> &'a syn::Type; } +pub trait ResolveType<'a> { fn resolve_type(&'a self, ty: &'a syn::Type) -> &'a syn::Type; } impl<'a, 'b, 'c: 'a + 'b> ResolveType<'c> for Option<&GenericTypes<'a, 'b>> { fn resolve_type(&'c self, ty: &'c syn::Type) -> &'c syn::Type { if let Some(us) = self { @@ -513,14 +513,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr }, syn::Item::Type(t) if export_status(&t.attrs) == ExportStatus::Export => { if let syn::Visibility::Public(_) = t.vis { - let mut process_alias = true; - for tok in t.generics.params.iter() { - if let syn::GenericParam::Lifetime(_) = tok {} - else { process_alias = false; } - } - if process_alias { - declared.insert(t.ident.clone(), DeclType::StructImported { generics: &t.generics }); - } + declared.insert(t.ident.clone(), DeclType::StructImported { generics: &t.generics }); } }, syn::Item::Enum(e) => { @@ -739,6 +732,8 @@ pub struct CrateTypes<'a> { /// This may contain structs or enums, but only when either is mapped as /// struct X { inner: *mut originalX, .. } pub opaques: HashMap, + /// structs that weren't exposed + pub priv_structs: HashMap, /// Enums which are mapped as C enums with conversion functions pub mirrored_enums: HashMap, /// Traits which are mapped as a pointer + jump table @@ -768,7 +763,7 @@ impl<'a> CrateTypes<'a> { CrateTypes { opaques: HashMap::new(), mirrored_enums: HashMap::new(), traits: HashMap::new(), type_aliases: HashMap::new(), reverse_alias_map: HashMap::new(), - templates_defined: RefCell::new(HashMap::default()), + templates_defined: RefCell::new(HashMap::default()), priv_structs: HashMap::new(), clonable_types: RefCell::new(initial_clonable_types()), trait_impls: HashMap::new(), template_file: RefCell::new(template_file), lib_ast: &libast, } @@ -1667,7 +1662,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { write!(w, ">").unwrap(); } pub fn write_rust_type(&self, w: &mut W, generics: Option<&GenericTypes>, t: &syn::Type) { - match t { + match generics.resolve_type(t) { syn::Type::Path(p) => { if p.qself.is_some() { unimplemented!(); @@ -2337,6 +2332,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } write!(w, "let mut local_{} = (", ident).unwrap(); for (idx, elem) in t.elems.iter().enumerate() { + let real_elem = generics.resolve_type(&elem); let ty_has_inner = { if to_c { // "To C ptr_for_ref" means "return the regular object with @@ -2344,16 +2340,16 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // if we're about to set ty_has_inner. ptr_for_ref = true; } - if let syn::Type::Reference(t) = elem { + if let syn::Type::Reference(t) = real_elem { if let syn::Type::Path(p) = &*t.elem { self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics)) } else { false } - } else if let syn::Type::Path(p) = elem { + } else if let syn::Type::Path(p) = real_elem { self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics)) } else { false } }; if idx != 0 { write!(w, ", ").unwrap(); } - var_prefix(w, elem, generics, is_ref && ty_has_inner, ptr_for_ref, false); + var_prefix(w, real_elem, generics, is_ref && ty_has_inner, ptr_for_ref, false); if is_ref && ty_has_inner { // For ty_has_inner, the regular var_prefix mapping will take a // reference, so deref once here to make sure we keep the original ref. @@ -2365,7 +2361,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // hope the type is Clonable and use that. write!(w, ".clone()").unwrap(); } - var_suffix(w, elem, generics, is_ref && ty_has_inner, ptr_for_ref, false); + var_suffix(w, real_elem, generics, is_ref && ty_has_inner, ptr_for_ref, false); } write!(w, "){};", if to_c { ".into()" } else { "" }).unwrap(); true @@ -2412,7 +2408,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { if let syn::Type::Reference(r_arg) = t { assert!(!is_ref); // We don't currently support outer reference types for non-primitive inners - if !self.write_c_type_intern(w, &*r_arg.elem, generics, false, false, false, false) { return false; } + if !self.write_c_type_intern(w, &*r_arg.elem, generics, false, false, false, true, true) { return false; } // While write_c_type_intern, above is correct, we don't want to blindly convert a // reference to something stupid, so check that the container is either opaque or a @@ -2430,7 +2426,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } else { assert!(!is_ref); // We don't currently support outer reference types for non-primitive inners } - if !self.write_c_type_intern(w, t, generics, false, false, false, false) { return false; } + if !self.write_c_type_intern(w, t, generics, false, false, false, true, true) { return false; } } else { // We don't currently support outer reference types for non-primitive inners, // except for the empty tuple. @@ -2439,7 +2435,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } else { assert!(!is_ref); } - if !self.write_c_type_intern(w, t, generics, false, false, false, false) { return false; } + if !self.write_c_type_intern(w, t, generics, false, false, false, true, true) { return false; } } } true @@ -2538,13 +2534,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { if self.is_transparent_container(ident, is_ref, args.iter().map(|a| *a), generics) { if !in_type { if self.c_type_has_inner_from_path(&subtype) { - if !self.write_c_path_intern(w, &$p_arg.path, generics, is_ref, is_mut, ptr_for_ref, false) { return false; } + if !self.write_c_path_intern(w, &$p_arg.path, generics, is_ref, is_mut, ptr_for_ref, false, true) { return false; } } else { if let Some(arr_ty) = self.is_real_type_array(&subtype) { - if !self.write_c_type_intern(w, &arr_ty, generics, false, true, false, false) { return false; } + if !self.write_c_type_intern(w, &arr_ty, generics, false, true, false, false, true) { return false; } } else { // Option needs to be converted to a *mut T, ie mut ptr-for-ref - if !self.write_c_path_intern(w, &$p_arg.path, generics, true, true, true, false) { return false; } + if !self.write_c_path_intern(w, &$p_arg.path, generics, true, true, true, false, true) { return false; } } } } else { @@ -2668,13 +2664,16 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // *** C Type Equivalent Printing *** // ********************************** - fn write_c_path_intern(&self, w: &mut W, path: &syn::Path, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool, with_ref_lifetime: bool) -> bool { + fn write_c_path_intern(&self, w: &mut W, path: &syn::Path, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool, with_ref_lifetime: bool, c_ty: bool) -> bool { let full_path = match self.maybe_resolve_path(&path, generics) { Some(path) => path, None => return false }; if let Some(c_type) = self.c_type_from_path(&full_path, is_ref, ptr_for_ref) { write!(w, "{}", c_type).unwrap(); true } else if self.crate_types.traits.get(&full_path).is_some() { + // Note that we always use the crate:: prefix here as we are always referring to a + // concrete object which is of the generated type, it just implements the upstream + // type. if is_ref && ptr_for_ref { write!(w, "*{} crate::{}", if is_mut { "mut" } else { "const" }, full_path).unwrap(); } else if is_ref { @@ -2685,29 +2684,34 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } true } else if self.crate_types.opaques.get(&full_path).is_some() || self.crate_types.mirrored_enums.get(&full_path).is_some() { + let crate_pfx = if c_ty { "crate::" } else { "" }; if is_ref && ptr_for_ref { // ptr_for_ref implies we're returning the object, which we can't really do for // opaque or mirrored types without box'ing them, which is quite a waste, so return // the actual object itself (for opaque types we'll set the pointer to the actual // type and note that its a reference). - write!(w, "crate::{}", full_path).unwrap(); + write!(w, "{}{}", crate_pfx, full_path).unwrap(); } else if is_ref && with_ref_lifetime { assert!(!is_mut); // If we're concretizing something with a lifetime parameter, we have to pick a // lifetime, of which the only real available choice is `static`, obviously. - write!(w, "&'static ").unwrap(); - self.write_rust_path(w, generics, path); + write!(w, "&'static {}", crate_pfx).unwrap(); + if !c_ty { + self.write_rust_path(w, generics, path); + } else { + write!(w, "{}", full_path).unwrap(); + } } else if is_ref { - write!(w, "&{}crate::{}", if is_mut { "mut " } else { "" }, full_path).unwrap(); + write!(w, "&{}{}{}", if is_mut { "mut " } else { "" }, crate_pfx, full_path).unwrap(); } else { - write!(w, "crate::{}", full_path).unwrap(); + write!(w, "{}{}", crate_pfx, full_path).unwrap(); } true } else { false } } - fn write_c_type_intern(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool, with_ref_lifetime: bool) -> bool { + fn write_c_type_intern(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool, with_ref_lifetime: bool, c_ty: bool) -> bool { match generics.resolve_type(t) { syn::Type::Path(p) => { if p.qself.is_some() { @@ -2718,24 +2722,24 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { return self.write_c_mangled_container_path(w, Self::path_to_generic_args(&p.path), generics, &full_path, is_ref, is_mut, ptr_for_ref); } if let Some(aliased_type) = self.crate_types.type_aliases.get(&full_path).cloned() { - return self.write_c_type_intern(w, &aliased_type, None, is_ref, is_mut, ptr_for_ref, with_ref_lifetime); + return self.write_c_type_intern(w, &aliased_type, None, is_ref, is_mut, ptr_for_ref, with_ref_lifetime, c_ty); } } - self.write_c_path_intern(w, &p.path, generics, is_ref, is_mut, ptr_for_ref, with_ref_lifetime) + self.write_c_path_intern(w, &p.path, generics, is_ref, is_mut, ptr_for_ref, with_ref_lifetime, c_ty) }, syn::Type::Reference(r) => { - self.write_c_type_intern(w, &*r.elem, generics, true, r.mutability.is_some(), ptr_for_ref, with_ref_lifetime) + self.write_c_type_intern(w, &*r.elem, generics, true, r.mutability.is_some(), ptr_for_ref, with_ref_lifetime, c_ty) }, syn::Type::Array(a) => { if is_ref && is_mut { write!(w, "*mut [").unwrap(); - if !self.write_c_type_intern(w, &a.elem, generics, false, false, ptr_for_ref, with_ref_lifetime) { return false; } + if !self.write_c_type_intern(w, &a.elem, generics, false, false, ptr_for_ref, with_ref_lifetime, c_ty) { return false; } } else if is_ref { write!(w, "*const [").unwrap(); - if !self.write_c_type_intern(w, &a.elem, generics, false, false, ptr_for_ref, with_ref_lifetime) { return false; } + if !self.write_c_type_intern(w, &a.elem, generics, false, false, ptr_for_ref, with_ref_lifetime, c_ty) { return false; } } else { let mut typecheck = Vec::new(); - if !self.write_c_type_intern(&mut typecheck, &a.elem, generics, false, false, ptr_for_ref, with_ref_lifetime) { return false; } + if !self.write_c_type_intern(&mut typecheck, &a.elem, generics, false, false, ptr_for_ref, with_ref_lifetime, c_ty) { return false; } if typecheck[..] != ['u' as u8, '8' as u8] { return false; } } if let syn::Expr::Lit(l) = &a.len { @@ -2761,7 +2765,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { true } else { let mut inner_c_ty = Vec::new(); - assert!(self.write_c_path_intern(&mut inner_c_ty, &p.path, generics, true, false, ptr_for_ref, with_ref_lifetime)); + assert!(self.write_c_path_intern(&mut inner_c_ty, &p.path, generics, true, false, ptr_for_ref, with_ref_lifetime, c_ty)); if self.is_clonable(&String::from_utf8(inner_c_ty).unwrap()) { if let Some(id) = p.path.get_ident() { let mangled_container = format!("CVec_{}Z", id); @@ -2803,7 +2807,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { args.push(syn::GenericArgument::Type((*s.elem).clone())); let mut segments = syn::punctuated::Punctuated::new(); segments.push(parse_quote!(Vec<#args>)); - self.write_c_type_intern(w, &syn::Type::Path(syn::TypePath { qself: None, path: syn::Path { leading_colon: None, segments } }), generics, false, is_mut, ptr_for_ref, with_ref_lifetime) + self.write_c_type_intern(w, &syn::Type::Path(syn::TypePath { qself: None, path: syn::Path { leading_colon: None, segments } }), generics, false, is_mut, ptr_for_ref, with_ref_lifetime, c_ty) } else { false } }, syn::Type::Tuple(t) => { @@ -2818,16 +2822,16 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } } pub fn write_c_type(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, ptr_for_ref: bool) { - assert!(self.write_c_type_intern(w, t, generics, false, false, ptr_for_ref, false)); + assert!(self.write_c_type_intern(w, t, generics, false, false, ptr_for_ref, false, true)); } pub fn write_c_type_in_generic_param(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, ptr_for_ref: bool) { - assert!(self.write_c_type_intern(w, t, generics, false, false, ptr_for_ref, true)); + assert!(self.write_c_type_intern(w, t, generics, false, false, ptr_for_ref, true, false)); } pub fn understood_c_path(&self, p: &syn::Path) -> bool { if p.leading_colon.is_some() { return false; } - self.write_c_path_intern(&mut std::io::sink(), p, None, false, false, false, false) + self.write_c_path_intern(&mut std::io::sink(), p, None, false, false, false, false, true) } pub fn understood_c_type(&self, t: &syn::Type, generics: Option<&GenericTypes>) -> bool { - self.write_c_type_intern(&mut std::io::sink(), t, generics, false, false, false, false) + self.write_c_type_intern(&mut std::io::sink(), t, generics, false, false, false, false, true) } } diff --git a/lightning-c-bindings/demo.cpp b/lightning-c-bindings/demo.cpp index 3b0c437..08bf66e 100644 --- a/lightning-c-bindings/demo.cpp +++ b/lightning-c-bindings/demo.cpp @@ -864,8 +864,8 @@ int main() { .find_route = custom_find_route, .free = NULL, }; - LDK::Scorer scorer = Scorer_default(); - LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(Scorer_as_Score(&scorer)); + LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1); + LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(ProbabilisticScorer_as_Score(&scorer)); EventQueue queue1; LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL }; LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, &scorer_mtx, logger1, handler1, RetryAttempts_new(0)); diff --git a/lightning-c-bindings/include/ldk_rust_types.h b/lightning-c-bindings/include/ldk_rust_types.h index eb35dae..f75de1c 100644 --- a/lightning-c-bindings/include/ldk_rust_types.h +++ b/lightning-c-bindings/include/ldk_rust_types.h @@ -66,6 +66,8 @@ struct nativeScorerOpaque; typedef struct nativeScorerOpaque LDKnativeScorer; struct nativeScoringParametersOpaque; typedef struct nativeScoringParametersOpaque LDKnativeScoringParameters; +struct nativeProbabilisticScorerOpaque; +typedef struct nativeProbabilisticScorerOpaque LDKnativeProbabilisticScorer; struct nativeProbabilisticScoringParametersOpaque; typedef struct nativeProbabilisticScoringParametersOpaque LDKnativeProbabilisticScoringParameters; struct nativeInitFeaturesOpaque; diff --git a/lightning-c-bindings/include/lightning.h b/lightning-c-bindings/include/lightning.h index f00bbc2..7274897 100644 --- a/lightning-c-bindings/include/lightning.h +++ b/lightning-c-bindings/include/lightning.h @@ -4290,6 +4290,114 @@ typedef struct LDKCResult_ProbabilisticScoringParametersDecodeErrorZ { +/** + * Represents the network as nodes and channels between them + */ +typedef struct MUST_USE_STRUCT LDKNetworkGraph { + /** + * A pointer to the opaque Rust object. + * Nearly everywhere, inner must be non-null, however in places where + * the Rust equivalent takes an Option, it may be set to null to indicate None. + */ + LDKnativeNetworkGraph *inner; + /** + * Indicates that this is the only struct which contains the same pointer. + * Rust functions which take ownership of an object provided via an argument require + * this to be true and invalidate the object pointed to by inner. + */ + bool is_owned; +} LDKNetworkGraph; + +/** + * A tuple of 2 elements. See the individual fields for the types contained. + */ +typedef struct LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ { + /** + * The element at position 0 + */ + struct LDKProbabilisticScoringParameters a; + /** + * The element at position 1 + */ + const struct LDKNetworkGraph *NONNULL_PTR b; +} LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ; + + + +/** + * [`Score`] implementation using channel success probability distributions. + * + * Based on *Optimally Reliable & Cheap Payment Flows on the Lightning Network* by Rene Pickhardt + * and Stefan Richter [[1]]. Given the uncertainty of channel liquidity balances, probability + * distributions are defined based on knowledge learned from successful and unsuccessful attempts. + * Then the negative `log10` of the success probability is used to determine the cost of routing a + * specific HTLC amount through a channel. + * + * Knowledge about channel liquidity balances takes the form of upper and lower bounds on the + * possible liquidity. Certainty of the bounds is decreased over time using a decay function. See + * [`ProbabilisticScoringParameters`] for details. + * + * Since the scorer aims to learn the current channel liquidity balances, it works best for nodes + * with high payment volume or that actively probe the [`NetworkGraph`]. Nodes with low payment + * volume are more likely to experience failed payment paths, which would need to be retried. + * + * # Note + * + * Mixing the `no-std` feature between serialization and deserialization results in undefined + * behavior. + * + * [1]: https://arxiv.org/abs/2107.05322 + */ +typedef struct MUST_USE_STRUCT LDKProbabilisticScorer { + /** + * A pointer to the opaque Rust object. + * Nearly everywhere, inner must be non-null, however in places where + * the Rust equivalent takes an Option, it may be set to null to indicate None. + */ + LDKnativeProbabilisticScorer *inner; + /** + * Indicates that this is the only struct which contains the same pointer. + * Rust functions which take ownership of an object provided via an argument require + * this to be true and invalidate the object pointed to by inner. + */ + bool is_owned; +} LDKProbabilisticScorer; + +/** + * The contents of CResult_ProbabilisticScorerDecodeErrorZ + */ +typedef union LDKCResult_ProbabilisticScorerDecodeErrorZPtr { + /** + * A pointer to the contents in the success state. + * Reading from this pointer when `result_ok` is not set is undefined. + */ + struct LDKProbabilisticScorer *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_ProbabilisticScorerDecodeErrorZPtr; + +/** + * A CResult_ProbabilisticScorerDecodeErrorZ represents the result of a fallible operation, + * containing a crate::lightning::routing::scoring::ProbabilisticScorer 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_ProbabilisticScorerDecodeErrorZ { + /** + * The contents of this CResult_ProbabilisticScorerDecodeErrorZ, accessible via either + * `err` or `result` depending on the state of `result_ok`. + */ + union LDKCResult_ProbabilisticScorerDecodeErrorZPtr contents; + /** + * Whether this CResult_ProbabilisticScorerDecodeErrorZ represents a success state. + */ + bool result_ok; +} LDKCResult_ProbabilisticScorerDecodeErrorZ; + + + /** * Features used within an `init` message. */ @@ -8719,26 +8827,6 @@ typedef struct LDKCResult_NodeInfoDecodeErrorZ { bool result_ok; } LDKCResult_NodeInfoDecodeErrorZ; - - -/** - * Represents the network as nodes and channels between them - */ -typedef struct MUST_USE_STRUCT LDKNetworkGraph { - /** - * A pointer to the opaque Rust object. - * Nearly everywhere, inner must be non-null, however in places where - * the Rust equivalent takes an Option, it may be set to null to indicate None. - */ - LDKnativeNetworkGraph *inner; - /** - * Indicates that this is the only struct which contains the same pointer. - * Rust functions which take ownership of an object provided via an argument require - * this to be true and invalidate the object pointed to by inner. - */ - bool is_owned; -} LDKNetworkGraph; - /** * The contents of CResult_NetworkGraphDecodeErrorZ */ @@ -12325,6 +12413,12 @@ bool CResult_SecretKeyErrorZ_is_ok(const struct LDKCResult_SecretKeyErrorZ *NONN */ void CResult_SecretKeyErrorZ_free(struct LDKCResult_SecretKeyErrorZ _res); +/** + * Creates a new CResult_SecretKeyErrorZ which has the same data as `orig` + * but with all dynamically-allocated buffers duplicated in new buffers. + */ +struct LDKCResult_SecretKeyErrorZ CResult_SecretKeyErrorZ_clone(const struct LDKCResult_SecretKeyErrorZ *NONNULL_PTR orig); + /** * Creates a new CResult_PublicKeyErrorZ in the success state. */ @@ -13313,6 +13407,36 @@ void CResult_ProbabilisticScoringParametersDecodeErrorZ_free(struct LDKCResult_P */ struct LDKCResult_ProbabilisticScoringParametersDecodeErrorZ CResult_ProbabilisticScoringParametersDecodeErrorZ_clone(const struct LDKCResult_ProbabilisticScoringParametersDecodeErrorZ *NONNULL_PTR orig); +/** + * Creates a new C2Tuple_ProbabilisticScoringParametersNetworkGraphZ from the contained elements. + */ +struct LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ C2Tuple_ProbabilisticScoringParametersNetworkGraphZ_new(struct LDKProbabilisticScoringParameters a, const struct LDKNetworkGraph *NONNULL_PTR b); + +/** + * Frees any resources used by the C2Tuple_ProbabilisticScoringParametersNetworkGraphZ. + */ +void C2Tuple_ProbabilisticScoringParametersNetworkGraphZ_free(struct LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ _res); + +/** + * Creates a new CResult_ProbabilisticScorerDecodeErrorZ in the success state. + */ +struct LDKCResult_ProbabilisticScorerDecodeErrorZ CResult_ProbabilisticScorerDecodeErrorZ_ok(struct LDKProbabilisticScorer o); + +/** + * Creates a new CResult_ProbabilisticScorerDecodeErrorZ in the error state. + */ +struct LDKCResult_ProbabilisticScorerDecodeErrorZ CResult_ProbabilisticScorerDecodeErrorZ_err(struct LDKDecodeError e); + +/** + * Checks if the given object is currently in the success state + */ +bool CResult_ProbabilisticScorerDecodeErrorZ_is_ok(const struct LDKCResult_ProbabilisticScorerDecodeErrorZ *NONNULL_PTR o); + +/** + * Frees any resources used by the CResult_ProbabilisticScorerDecodeErrorZ. + */ +void CResult_ProbabilisticScorerDecodeErrorZ_free(struct LDKCResult_ProbabilisticScorerDecodeErrorZ _res); + /** * Creates a new CResult_InitFeaturesDecodeErrorZ in the success state. */ @@ -13626,6 +13750,12 @@ bool CResult_SecretKeyNoneZ_is_ok(const struct LDKCResult_SecretKeyNoneZ *NONNUL */ void CResult_SecretKeyNoneZ_free(struct LDKCResult_SecretKeyNoneZ _res); +/** + * Creates a new CResult_SecretKeyNoneZ which has the same data as `orig` + * but with all dynamically-allocated buffers duplicated in new buffers. + */ +struct LDKCResult_SecretKeyNoneZ CResult_SecretKeyNoneZ_clone(const struct LDKCResult_SecretKeyNoneZ *NONNULL_PTR orig); + /** * Creates a new CResult_SignDecodeErrorZ in the success state. */ @@ -25237,6 +25367,11 @@ struct LDKCVec_u8Z Scorer_write(const struct LDKScorer *NONNULL_PTR obj); */ struct LDKCResult_ScorerDecodeErrorZ Scorer_read(struct LDKu8slice ser); +/** + * Frees any resources used by the ProbabilisticScorer, if is_owned is set and inner is non-NULL. + */ +void ProbabilisticScorer_free(struct LDKProbabilisticScorer this_obj); + /** * Frees any resources used by the ProbabilisticScoringParameters, if is_owned is set and inner is non-NULL. */ @@ -25330,11 +25465,33 @@ struct LDKCVec_u8Z ProbabilisticScoringParameters_write(const struct LDKProbabil */ struct LDKCResult_ProbabilisticScoringParametersDecodeErrorZ ProbabilisticScoringParameters_read(struct LDKu8slice ser); +/** + * Creates a new scorer using the given scoring parameters for sending payments from a node + * through a network graph. + */ +MUST_USE_RES struct LDKProbabilisticScorer ProbabilisticScorer_new(struct LDKProbabilisticScoringParameters params, const struct LDKNetworkGraph *NONNULL_PTR network_graph); + /** * Creates a "default" ProbabilisticScoringParameters. See struct and individual field documentaiton for details on which values are used. */ MUST_USE_RES struct LDKProbabilisticScoringParameters ProbabilisticScoringParameters_default(void); +/** + * Constructs a new Score which calls the relevant methods on this_arg. + * This copies the `inner` pointer in this_arg and thus the returned Score must be freed before this_arg is + */ +struct LDKScore ProbabilisticScorer_as_Score(const struct LDKProbabilisticScorer *NONNULL_PTR this_arg); + +/** + * Serialize the ProbabilisticScorer object into a byte array which can be read by ProbabilisticScorer_read + */ +struct LDKCVec_u8Z ProbabilisticScorer_write(const struct LDKProbabilisticScorer *NONNULL_PTR obj); + +/** + * Read a ProbabilisticScorer from a byte array, created by ProbabilisticScorer_write + */ +struct LDKCResult_ProbabilisticScorerDecodeErrorZ ProbabilisticScorer_read(struct LDKu8slice ser, struct LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ arg); + /** * Frees any resources used by the FilesystemPersister, if is_owned is set and inner is non-NULL. */ diff --git a/lightning-c-bindings/include/lightningpp.hpp b/lightning-c-bindings/include/lightningpp.hpp index 5092728..5a18979 100644 --- a/lightning-c-bindings/include/lightningpp.hpp +++ b/lightning-c-bindings/include/lightningpp.hpp @@ -50,6 +50,7 @@ class MultiThreadedLockableScore; class FixedPenaltyScorer; class Scorer; class ScoringParameters; +class ProbabilisticScorer; class ProbabilisticScoringParameters; class InitFeatures; class NodeFeatures; @@ -208,8 +209,8 @@ class CResult_ChannelReestablishDecodeErrorZ; class CResult_CommitmentSignedDecodeErrorZ; class CVec_UpdateAddHTLCZ; class CResult_UnsignedNodeAnnouncementDecodeErrorZ; -class COption_u32Z; class CResult_InitFeaturesDecodeErrorZ; +class COption_u32Z; class CResult_StaticPaymentOutputDescriptorDecodeErrorZ; class CResult_PaymentIdPaymentSendFailureZ; class CResult_ReplyChannelRangeDecodeErrorZ; @@ -226,10 +227,10 @@ class CResult_ErrorMessageDecodeErrorZ; class CResult_OpenChannelDecodeErrorZ; class CVec_CVec_u8ZZ; class COption_FilterZ; +class CResult_ProbabilisticScorerDecodeErrorZ; class CResult_SecretKeyErrorZ; class CResult_ShutdownScriptDecodeErrorZ; class CResult_InvoiceNoneZ; -class CResult_QueryChannelRangeDecodeErrorZ; class CResult_TxCreationKeysDecodeErrorZ; class C2Tuple_usizeTransactionZ; class CResult_ChannelFeaturesDecodeErrorZ; @@ -238,6 +239,7 @@ class CVec_TransactionZ; class CResult_UpdateFeeDecodeErrorZ; class CResult_RouteHopDecodeErrorZ; class CResult_NodeAnnouncementDecodeErrorZ; +class CResult_QueryChannelRangeDecodeErrorZ; class CVec_BalanceZ; class CResult_HTLCOutputInCommitmentDecodeErrorZ; class CResult_boolLightningErrorZ; @@ -316,23 +318,24 @@ class CResult_NonePeerHandleErrorZ; class CResult_COption_EventZDecodeErrorZ; class CResult_CVec_SignatureZNoneZ; class COption_CVec_NetAddressZZ; +class C2Tuple_ProbabilisticScoringParametersNetworkGraphZ; class CResult__u832APIErrorZ; class CResult_PaymentIdPaymentErrorZ; class CResult_DescriptionCreationErrorZ; -class CResult_COption_MonitorEventZDecodeErrorZ; class CResult_PayeePubKeyErrorZ; +class CResult_COption_MonitorEventZDecodeErrorZ; class CVec_C2Tuple_PublicKeyTypeZZ; class CResult_RoutingFeesDecodeErrorZ; -class CResult_QueryShortChannelIdsDecodeErrorZ; class CResult_InvoiceSemanticErrorZ; class CResult_UpdateAddHTLCDecodeErrorZ; -class CVec_PhantomRouteHintsZ; +class CResult_QueryShortChannelIdsDecodeErrorZ; class CResult_CounterpartyChannelTransactionParametersDecodeErrorZ; class CResult_NoneAPIErrorZ; class CVec_NetAddressZ; class CResult_ChannelDetailsDecodeErrorZ; class CVec_C2Tuple_usizeTransactionZZ; class CVec_PublicKeyZ; +class CVec_PhantomRouteHintsZ; class COption_MonitorEventZ; class COption_TypeZ; class CResult_COption_TypeZDecodeErrorZ; @@ -1297,6 +1300,21 @@ public: const LDKScoringParameters* operator &() const { return &self; } const LDKScoringParameters* operator ->() const { return &self; } }; +class ProbabilisticScorer { +private: + LDKProbabilisticScorer self; +public: + ProbabilisticScorer(const ProbabilisticScorer&) = delete; + ProbabilisticScorer(ProbabilisticScorer&& o) : self(o.self) { memset(&o, 0, sizeof(ProbabilisticScorer)); } + ProbabilisticScorer(LDKProbabilisticScorer&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKProbabilisticScorer)); } + operator LDKProbabilisticScorer() && { LDKProbabilisticScorer res = self; memset(&self, 0, sizeof(LDKProbabilisticScorer)); return res; } + ~ProbabilisticScorer() { ProbabilisticScorer_free(self); } + ProbabilisticScorer& operator=(ProbabilisticScorer&& o) { ProbabilisticScorer_free(self); self = o.self; memset(&o, 0, sizeof(ProbabilisticScorer)); return *this; } + LDKProbabilisticScorer* operator &() { return &self; } + LDKProbabilisticScorer* operator ->() { return &self; } + const LDKProbabilisticScorer* operator &() const { return &self; } + const LDKProbabilisticScorer* operator ->() const { return &self; } +}; class ProbabilisticScoringParameters { private: LDKProbabilisticScoringParameters self; @@ -4188,21 +4206,6 @@ public: const LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ* operator &() const { return &self; } const LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ* operator ->() const { return &self; } }; -class COption_u32Z { -private: - LDKCOption_u32Z self; -public: - COption_u32Z(const COption_u32Z&) = delete; - COption_u32Z(COption_u32Z&& o) : self(o.self) { memset(&o, 0, sizeof(COption_u32Z)); } - COption_u32Z(LDKCOption_u32Z&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCOption_u32Z)); } - operator LDKCOption_u32Z() && { LDKCOption_u32Z res = self; memset(&self, 0, sizeof(LDKCOption_u32Z)); return res; } - ~COption_u32Z() { COption_u32Z_free(self); } - COption_u32Z& operator=(COption_u32Z&& o) { COption_u32Z_free(self); self = o.self; memset(&o, 0, sizeof(COption_u32Z)); return *this; } - LDKCOption_u32Z* operator &() { return &self; } - LDKCOption_u32Z* operator ->() { return &self; } - const LDKCOption_u32Z* operator &() const { return &self; } - const LDKCOption_u32Z* operator ->() const { return &self; } -}; class CResult_InitFeaturesDecodeErrorZ { private: LDKCResult_InitFeaturesDecodeErrorZ self; @@ -4218,6 +4221,21 @@ public: const LDKCResult_InitFeaturesDecodeErrorZ* operator &() const { return &self; } const LDKCResult_InitFeaturesDecodeErrorZ* operator ->() const { return &self; } }; +class COption_u32Z { +private: + LDKCOption_u32Z self; +public: + COption_u32Z(const COption_u32Z&) = delete; + COption_u32Z(COption_u32Z&& o) : self(o.self) { memset(&o, 0, sizeof(COption_u32Z)); } + COption_u32Z(LDKCOption_u32Z&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCOption_u32Z)); } + operator LDKCOption_u32Z() && { LDKCOption_u32Z res = self; memset(&self, 0, sizeof(LDKCOption_u32Z)); return res; } + ~COption_u32Z() { COption_u32Z_free(self); } + COption_u32Z& operator=(COption_u32Z&& o) { COption_u32Z_free(self); self = o.self; memset(&o, 0, sizeof(COption_u32Z)); return *this; } + LDKCOption_u32Z* operator &() { return &self; } + LDKCOption_u32Z* operator ->() { return &self; } + const LDKCOption_u32Z* operator &() const { return &self; } + const LDKCOption_u32Z* operator ->() const { return &self; } +}; class CResult_StaticPaymentOutputDescriptorDecodeErrorZ { private: LDKCResult_StaticPaymentOutputDescriptorDecodeErrorZ self; @@ -4458,6 +4476,21 @@ public: const LDKCOption_FilterZ* operator &() const { return &self; } const LDKCOption_FilterZ* operator ->() const { return &self; } }; +class CResult_ProbabilisticScorerDecodeErrorZ { +private: + LDKCResult_ProbabilisticScorerDecodeErrorZ self; +public: + CResult_ProbabilisticScorerDecodeErrorZ(const CResult_ProbabilisticScorerDecodeErrorZ&) = delete; + CResult_ProbabilisticScorerDecodeErrorZ(CResult_ProbabilisticScorerDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_ProbabilisticScorerDecodeErrorZ)); } + CResult_ProbabilisticScorerDecodeErrorZ(LDKCResult_ProbabilisticScorerDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_ProbabilisticScorerDecodeErrorZ)); } + operator LDKCResult_ProbabilisticScorerDecodeErrorZ() && { LDKCResult_ProbabilisticScorerDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_ProbabilisticScorerDecodeErrorZ)); return res; } + ~CResult_ProbabilisticScorerDecodeErrorZ() { CResult_ProbabilisticScorerDecodeErrorZ_free(self); } + CResult_ProbabilisticScorerDecodeErrorZ& operator=(CResult_ProbabilisticScorerDecodeErrorZ&& o) { CResult_ProbabilisticScorerDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_ProbabilisticScorerDecodeErrorZ)); return *this; } + LDKCResult_ProbabilisticScorerDecodeErrorZ* operator &() { return &self; } + LDKCResult_ProbabilisticScorerDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_ProbabilisticScorerDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_ProbabilisticScorerDecodeErrorZ* operator ->() const { return &self; } +}; class CResult_SecretKeyErrorZ { private: LDKCResult_SecretKeyErrorZ self; @@ -4503,21 +4536,6 @@ public: const LDKCResult_InvoiceNoneZ* operator &() const { return &self; } const LDKCResult_InvoiceNoneZ* operator ->() const { return &self; } }; -class CResult_QueryChannelRangeDecodeErrorZ { -private: - LDKCResult_QueryChannelRangeDecodeErrorZ self; -public: - CResult_QueryChannelRangeDecodeErrorZ(const CResult_QueryChannelRangeDecodeErrorZ&) = delete; - CResult_QueryChannelRangeDecodeErrorZ(CResult_QueryChannelRangeDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_QueryChannelRangeDecodeErrorZ)); } - CResult_QueryChannelRangeDecodeErrorZ(LDKCResult_QueryChannelRangeDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_QueryChannelRangeDecodeErrorZ)); } - operator LDKCResult_QueryChannelRangeDecodeErrorZ() && { LDKCResult_QueryChannelRangeDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_QueryChannelRangeDecodeErrorZ)); return res; } - ~CResult_QueryChannelRangeDecodeErrorZ() { CResult_QueryChannelRangeDecodeErrorZ_free(self); } - CResult_QueryChannelRangeDecodeErrorZ& operator=(CResult_QueryChannelRangeDecodeErrorZ&& o) { CResult_QueryChannelRangeDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_QueryChannelRangeDecodeErrorZ)); return *this; } - LDKCResult_QueryChannelRangeDecodeErrorZ* operator &() { return &self; } - LDKCResult_QueryChannelRangeDecodeErrorZ* operator ->() { return &self; } - const LDKCResult_QueryChannelRangeDecodeErrorZ* operator &() const { return &self; } - const LDKCResult_QueryChannelRangeDecodeErrorZ* operator ->() const { return &self; } -}; class CResult_TxCreationKeysDecodeErrorZ { private: LDKCResult_TxCreationKeysDecodeErrorZ self; @@ -4638,6 +4656,21 @@ public: const LDKCResult_NodeAnnouncementDecodeErrorZ* operator &() const { return &self; } const LDKCResult_NodeAnnouncementDecodeErrorZ* operator ->() const { return &self; } }; +class CResult_QueryChannelRangeDecodeErrorZ { +private: + LDKCResult_QueryChannelRangeDecodeErrorZ self; +public: + CResult_QueryChannelRangeDecodeErrorZ(const CResult_QueryChannelRangeDecodeErrorZ&) = delete; + CResult_QueryChannelRangeDecodeErrorZ(CResult_QueryChannelRangeDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_QueryChannelRangeDecodeErrorZ)); } + CResult_QueryChannelRangeDecodeErrorZ(LDKCResult_QueryChannelRangeDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_QueryChannelRangeDecodeErrorZ)); } + operator LDKCResult_QueryChannelRangeDecodeErrorZ() && { LDKCResult_QueryChannelRangeDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_QueryChannelRangeDecodeErrorZ)); return res; } + ~CResult_QueryChannelRangeDecodeErrorZ() { CResult_QueryChannelRangeDecodeErrorZ_free(self); } + CResult_QueryChannelRangeDecodeErrorZ& operator=(CResult_QueryChannelRangeDecodeErrorZ&& o) { CResult_QueryChannelRangeDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_QueryChannelRangeDecodeErrorZ)); return *this; } + LDKCResult_QueryChannelRangeDecodeErrorZ* operator &() { return &self; } + LDKCResult_QueryChannelRangeDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_QueryChannelRangeDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_QueryChannelRangeDecodeErrorZ* operator ->() const { return &self; } +}; class CVec_BalanceZ { private: LDKCVec_BalanceZ self; @@ -5808,6 +5841,21 @@ public: const LDKCOption_CVec_NetAddressZZ* operator &() const { return &self; } const LDKCOption_CVec_NetAddressZZ* operator ->() const { return &self; } }; +class C2Tuple_ProbabilisticScoringParametersNetworkGraphZ { +private: + LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ self; +public: + C2Tuple_ProbabilisticScoringParametersNetworkGraphZ(const C2Tuple_ProbabilisticScoringParametersNetworkGraphZ&) = delete; + C2Tuple_ProbabilisticScoringParametersNetworkGraphZ(C2Tuple_ProbabilisticScoringParametersNetworkGraphZ&& o) : self(o.self) { memset(&o, 0, sizeof(C2Tuple_ProbabilisticScoringParametersNetworkGraphZ)); } + C2Tuple_ProbabilisticScoringParametersNetworkGraphZ(LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ)); } + operator LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ() && { LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ res = self; memset(&self, 0, sizeof(LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ)); return res; } + ~C2Tuple_ProbabilisticScoringParametersNetworkGraphZ() { C2Tuple_ProbabilisticScoringParametersNetworkGraphZ_free(self); } + C2Tuple_ProbabilisticScoringParametersNetworkGraphZ& operator=(C2Tuple_ProbabilisticScoringParametersNetworkGraphZ&& o) { C2Tuple_ProbabilisticScoringParametersNetworkGraphZ_free(self); self = o.self; memset(&o, 0, sizeof(C2Tuple_ProbabilisticScoringParametersNetworkGraphZ)); return *this; } + LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ* operator &() { return &self; } + LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ* operator ->() { return &self; } + const LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ* operator &() const { return &self; } + const LDKC2Tuple_ProbabilisticScoringParametersNetworkGraphZ* operator ->() const { return &self; } +}; class CResult__u832APIErrorZ { private: LDKCResult__u832APIErrorZ self; @@ -5853,21 +5901,6 @@ public: const LDKCResult_DescriptionCreationErrorZ* operator &() const { return &self; } const LDKCResult_DescriptionCreationErrorZ* operator ->() const { return &self; } }; -class CResult_COption_MonitorEventZDecodeErrorZ { -private: - LDKCResult_COption_MonitorEventZDecodeErrorZ self; -public: - CResult_COption_MonitorEventZDecodeErrorZ(const CResult_COption_MonitorEventZDecodeErrorZ&) = delete; - CResult_COption_MonitorEventZDecodeErrorZ(CResult_COption_MonitorEventZDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_COption_MonitorEventZDecodeErrorZ)); } - CResult_COption_MonitorEventZDecodeErrorZ(LDKCResult_COption_MonitorEventZDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_COption_MonitorEventZDecodeErrorZ)); } - operator LDKCResult_COption_MonitorEventZDecodeErrorZ() && { LDKCResult_COption_MonitorEventZDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_COption_MonitorEventZDecodeErrorZ)); return res; } - ~CResult_COption_MonitorEventZDecodeErrorZ() { CResult_COption_MonitorEventZDecodeErrorZ_free(self); } - CResult_COption_MonitorEventZDecodeErrorZ& operator=(CResult_COption_MonitorEventZDecodeErrorZ&& o) { CResult_COption_MonitorEventZDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_COption_MonitorEventZDecodeErrorZ)); return *this; } - LDKCResult_COption_MonitorEventZDecodeErrorZ* operator &() { return &self; } - LDKCResult_COption_MonitorEventZDecodeErrorZ* operator ->() { return &self; } - const LDKCResult_COption_MonitorEventZDecodeErrorZ* operator &() const { return &self; } - const LDKCResult_COption_MonitorEventZDecodeErrorZ* operator ->() const { return &self; } -}; class CResult_PayeePubKeyErrorZ { private: LDKCResult_PayeePubKeyErrorZ self; @@ -5883,6 +5916,21 @@ public: const LDKCResult_PayeePubKeyErrorZ* operator &() const { return &self; } const LDKCResult_PayeePubKeyErrorZ* operator ->() const { return &self; } }; +class CResult_COption_MonitorEventZDecodeErrorZ { +private: + LDKCResult_COption_MonitorEventZDecodeErrorZ self; +public: + CResult_COption_MonitorEventZDecodeErrorZ(const CResult_COption_MonitorEventZDecodeErrorZ&) = delete; + CResult_COption_MonitorEventZDecodeErrorZ(CResult_COption_MonitorEventZDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_COption_MonitorEventZDecodeErrorZ)); } + CResult_COption_MonitorEventZDecodeErrorZ(LDKCResult_COption_MonitorEventZDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_COption_MonitorEventZDecodeErrorZ)); } + operator LDKCResult_COption_MonitorEventZDecodeErrorZ() && { LDKCResult_COption_MonitorEventZDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_COption_MonitorEventZDecodeErrorZ)); return res; } + ~CResult_COption_MonitorEventZDecodeErrorZ() { CResult_COption_MonitorEventZDecodeErrorZ_free(self); } + CResult_COption_MonitorEventZDecodeErrorZ& operator=(CResult_COption_MonitorEventZDecodeErrorZ&& o) { CResult_COption_MonitorEventZDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_COption_MonitorEventZDecodeErrorZ)); return *this; } + LDKCResult_COption_MonitorEventZDecodeErrorZ* operator &() { return &self; } + LDKCResult_COption_MonitorEventZDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_COption_MonitorEventZDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_COption_MonitorEventZDecodeErrorZ* operator ->() const { return &self; } +}; class CVec_C2Tuple_PublicKeyTypeZZ { private: LDKCVec_C2Tuple_PublicKeyTypeZZ self; @@ -5913,21 +5961,6 @@ public: const LDKCResult_RoutingFeesDecodeErrorZ* operator &() const { return &self; } const LDKCResult_RoutingFeesDecodeErrorZ* operator ->() const { return &self; } }; -class CResult_QueryShortChannelIdsDecodeErrorZ { -private: - LDKCResult_QueryShortChannelIdsDecodeErrorZ self; -public: - CResult_QueryShortChannelIdsDecodeErrorZ(const CResult_QueryShortChannelIdsDecodeErrorZ&) = delete; - CResult_QueryShortChannelIdsDecodeErrorZ(CResult_QueryShortChannelIdsDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_QueryShortChannelIdsDecodeErrorZ)); } - CResult_QueryShortChannelIdsDecodeErrorZ(LDKCResult_QueryShortChannelIdsDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_QueryShortChannelIdsDecodeErrorZ)); } - operator LDKCResult_QueryShortChannelIdsDecodeErrorZ() && { LDKCResult_QueryShortChannelIdsDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_QueryShortChannelIdsDecodeErrorZ)); return res; } - ~CResult_QueryShortChannelIdsDecodeErrorZ() { CResult_QueryShortChannelIdsDecodeErrorZ_free(self); } - CResult_QueryShortChannelIdsDecodeErrorZ& operator=(CResult_QueryShortChannelIdsDecodeErrorZ&& o) { CResult_QueryShortChannelIdsDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_QueryShortChannelIdsDecodeErrorZ)); return *this; } - LDKCResult_QueryShortChannelIdsDecodeErrorZ* operator &() { return &self; } - LDKCResult_QueryShortChannelIdsDecodeErrorZ* operator ->() { return &self; } - const LDKCResult_QueryShortChannelIdsDecodeErrorZ* operator &() const { return &self; } - const LDKCResult_QueryShortChannelIdsDecodeErrorZ* operator ->() const { return &self; } -}; class CResult_InvoiceSemanticErrorZ { private: LDKCResult_InvoiceSemanticErrorZ self; @@ -5958,20 +5991,20 @@ public: const LDKCResult_UpdateAddHTLCDecodeErrorZ* operator &() const { return &self; } const LDKCResult_UpdateAddHTLCDecodeErrorZ* operator ->() const { return &self; } }; -class CVec_PhantomRouteHintsZ { +class CResult_QueryShortChannelIdsDecodeErrorZ { private: - LDKCVec_PhantomRouteHintsZ self; + LDKCResult_QueryShortChannelIdsDecodeErrorZ self; public: - CVec_PhantomRouteHintsZ(const CVec_PhantomRouteHintsZ&) = delete; - CVec_PhantomRouteHintsZ(CVec_PhantomRouteHintsZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_PhantomRouteHintsZ)); } - CVec_PhantomRouteHintsZ(LDKCVec_PhantomRouteHintsZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_PhantomRouteHintsZ)); } - operator LDKCVec_PhantomRouteHintsZ() && { LDKCVec_PhantomRouteHintsZ res = self; memset(&self, 0, sizeof(LDKCVec_PhantomRouteHintsZ)); return res; } - ~CVec_PhantomRouteHintsZ() { CVec_PhantomRouteHintsZ_free(self); } - CVec_PhantomRouteHintsZ& operator=(CVec_PhantomRouteHintsZ&& o) { CVec_PhantomRouteHintsZ_free(self); self = o.self; memset(&o, 0, sizeof(CVec_PhantomRouteHintsZ)); return *this; } - LDKCVec_PhantomRouteHintsZ* operator &() { return &self; } - LDKCVec_PhantomRouteHintsZ* operator ->() { return &self; } - const LDKCVec_PhantomRouteHintsZ* operator &() const { return &self; } - const LDKCVec_PhantomRouteHintsZ* operator ->() const { return &self; } + CResult_QueryShortChannelIdsDecodeErrorZ(const CResult_QueryShortChannelIdsDecodeErrorZ&) = delete; + CResult_QueryShortChannelIdsDecodeErrorZ(CResult_QueryShortChannelIdsDecodeErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_QueryShortChannelIdsDecodeErrorZ)); } + CResult_QueryShortChannelIdsDecodeErrorZ(LDKCResult_QueryShortChannelIdsDecodeErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_QueryShortChannelIdsDecodeErrorZ)); } + operator LDKCResult_QueryShortChannelIdsDecodeErrorZ() && { LDKCResult_QueryShortChannelIdsDecodeErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_QueryShortChannelIdsDecodeErrorZ)); return res; } + ~CResult_QueryShortChannelIdsDecodeErrorZ() { CResult_QueryShortChannelIdsDecodeErrorZ_free(self); } + CResult_QueryShortChannelIdsDecodeErrorZ& operator=(CResult_QueryShortChannelIdsDecodeErrorZ&& o) { CResult_QueryShortChannelIdsDecodeErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_QueryShortChannelIdsDecodeErrorZ)); return *this; } + LDKCResult_QueryShortChannelIdsDecodeErrorZ* operator &() { return &self; } + LDKCResult_QueryShortChannelIdsDecodeErrorZ* operator ->() { return &self; } + const LDKCResult_QueryShortChannelIdsDecodeErrorZ* operator &() const { return &self; } + const LDKCResult_QueryShortChannelIdsDecodeErrorZ* operator ->() const { return &self; } }; class CResult_CounterpartyChannelTransactionParametersDecodeErrorZ { private: @@ -6063,6 +6096,21 @@ public: const LDKCVec_PublicKeyZ* operator &() const { return &self; } const LDKCVec_PublicKeyZ* operator ->() const { return &self; } }; +class CVec_PhantomRouteHintsZ { +private: + LDKCVec_PhantomRouteHintsZ self; +public: + CVec_PhantomRouteHintsZ(const CVec_PhantomRouteHintsZ&) = delete; + CVec_PhantomRouteHintsZ(CVec_PhantomRouteHintsZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_PhantomRouteHintsZ)); } + CVec_PhantomRouteHintsZ(LDKCVec_PhantomRouteHintsZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_PhantomRouteHintsZ)); } + operator LDKCVec_PhantomRouteHintsZ() && { LDKCVec_PhantomRouteHintsZ res = self; memset(&self, 0, sizeof(LDKCVec_PhantomRouteHintsZ)); return res; } + ~CVec_PhantomRouteHintsZ() { CVec_PhantomRouteHintsZ_free(self); } + CVec_PhantomRouteHintsZ& operator=(CVec_PhantomRouteHintsZ&& o) { CVec_PhantomRouteHintsZ_free(self); self = o.self; memset(&o, 0, sizeof(CVec_PhantomRouteHintsZ)); return *this; } + LDKCVec_PhantomRouteHintsZ* operator &() { return &self; } + LDKCVec_PhantomRouteHintsZ* operator ->() { return &self; } + const LDKCVec_PhantomRouteHintsZ* operator &() const { return &self; } + const LDKCVec_PhantomRouteHintsZ* operator ->() const { return &self; } +}; class COption_MonitorEventZ { private: LDKCOption_MonitorEventZ self; diff --git a/lightning-c-bindings/src/c_types/derived.rs b/lightning-c-bindings/src/c_types/derived.rs index b531374..6c18446 100644 --- a/lightning-c-bindings/src/c_types/derived.rs +++ b/lightning-c-bindings/src/c_types/derived.rs @@ -270,6 +270,23 @@ impl From Self { + if self.result_ok { + Self { result_ok: true, contents: CResult_SecretKeyErrorZPtr { + result: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.result }))) + } } + } else { + Self { result_ok: false, contents: CResult_SecretKeyErrorZPtr { + err: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.err }))) + } } + } + } +} +#[no_mangle] +/// Creates a new CResult_SecretKeyErrorZ which has the same data as `orig` +/// but with all dynamically-allocated buffers duplicated in new buffers. +pub extern "C" fn CResult_SecretKeyErrorZ_clone(orig: &CResult_SecretKeyErrorZ) -> CResult_SecretKeyErrorZ { Clone::clone(&orig) } #[repr(C)] /// The contents of CResult_PublicKeyErrorZ pub union CResult_PublicKeyErrorZPtr { @@ -3941,6 +3958,115 @@ impl Clone for CResult_ProbabilisticScoringParametersDecodeErrorZ { /// but with all dynamically-allocated buffers duplicated in new buffers. pub extern "C" fn CResult_ProbabilisticScoringParametersDecodeErrorZ_clone(orig: &CResult_ProbabilisticScoringParametersDecodeErrorZ) -> CResult_ProbabilisticScoringParametersDecodeErrorZ { Clone::clone(&orig) } #[repr(C)] +/// A tuple of 2 elements. See the individual fields for the types contained. +pub struct C2Tuple_ProbabilisticScoringParametersNetworkGraphZ { + /// The element at position 0 + pub a: crate::lightning::routing::scoring::ProbabilisticScoringParameters, + /// The element at position 1 + pub b: &'static crate::lightning::routing::network_graph::NetworkGraph, +} +impl From<(crate::lightning::routing::scoring::ProbabilisticScoringParameters, &'static crate::lightning::routing::network_graph::NetworkGraph)> for C2Tuple_ProbabilisticScoringParametersNetworkGraphZ { + fn from (tup: (crate::lightning::routing::scoring::ProbabilisticScoringParameters, &'static crate::lightning::routing::network_graph::NetworkGraph)) -> Self { + Self { + a: tup.0, + b: tup.1, + } + } +} +impl C2Tuple_ProbabilisticScoringParametersNetworkGraphZ { + #[allow(unused)] pub(crate) fn to_rust(mut self) -> (crate::lightning::routing::scoring::ProbabilisticScoringParameters, &'static crate::lightning::routing::network_graph::NetworkGraph) { + (self.a, self.b) + } +} +/// Creates a new C2Tuple_ProbabilisticScoringParametersNetworkGraphZ from the contained elements. +#[no_mangle] +pub extern "C" fn C2Tuple_ProbabilisticScoringParametersNetworkGraphZ_new(a: crate::lightning::routing::scoring::ProbabilisticScoringParameters, b: &'static crate::lightning::routing::network_graph::NetworkGraph) -> C2Tuple_ProbabilisticScoringParametersNetworkGraphZ { + C2Tuple_ProbabilisticScoringParametersNetworkGraphZ { a, b, } +} + +#[no_mangle] +/// Frees any resources used by the C2Tuple_ProbabilisticScoringParametersNetworkGraphZ. +pub extern "C" fn C2Tuple_ProbabilisticScoringParametersNetworkGraphZ_free(_res: C2Tuple_ProbabilisticScoringParametersNetworkGraphZ) { } +#[repr(C)] +/// The contents of CResult_ProbabilisticScorerDecodeErrorZ +pub union CResult_ProbabilisticScorerDecodeErrorZPtr { + /// 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::routing::scoring::ProbabilisticScorer, + /// 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_ProbabilisticScorerDecodeErrorZ represents the result of a fallible operation, +/// containing a crate::lightning::routing::scoring::ProbabilisticScorer 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_ProbabilisticScorerDecodeErrorZ { + /// The contents of this CResult_ProbabilisticScorerDecodeErrorZ, accessible via either + /// `err` or `result` depending on the state of `result_ok`. + pub contents: CResult_ProbabilisticScorerDecodeErrorZPtr, + /// Whether this CResult_ProbabilisticScorerDecodeErrorZ represents a success state. + pub result_ok: bool, +} +#[no_mangle] +/// Creates a new CResult_ProbabilisticScorerDecodeErrorZ in the success state. +pub extern "C" fn CResult_ProbabilisticScorerDecodeErrorZ_ok(o: crate::lightning::routing::scoring::ProbabilisticScorer) -> CResult_ProbabilisticScorerDecodeErrorZ { + CResult_ProbabilisticScorerDecodeErrorZ { + contents: CResult_ProbabilisticScorerDecodeErrorZPtr { + result: Box::into_raw(Box::new(o)), + }, + result_ok: true, + } +} +#[no_mangle] +/// Creates a new CResult_ProbabilisticScorerDecodeErrorZ in the error state. +pub extern "C" fn CResult_ProbabilisticScorerDecodeErrorZ_err(e: crate::lightning::ln::msgs::DecodeError) -> CResult_ProbabilisticScorerDecodeErrorZ { + CResult_ProbabilisticScorerDecodeErrorZ { + contents: CResult_ProbabilisticScorerDecodeErrorZPtr { + err: Box::into_raw(Box::new(e)), + }, + result_ok: false, + } +} +/// Checks if the given object is currently in the success state +#[no_mangle] +pub extern "C" fn CResult_ProbabilisticScorerDecodeErrorZ_is_ok(o: &CResult_ProbabilisticScorerDecodeErrorZ) -> bool { + o.result_ok +} +#[no_mangle] +/// Frees any resources used by the CResult_ProbabilisticScorerDecodeErrorZ. +pub extern "C" fn CResult_ProbabilisticScorerDecodeErrorZ_free(_res: CResult_ProbabilisticScorerDecodeErrorZ) { } +impl Drop for CResult_ProbabilisticScorerDecodeErrorZ { + 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_ProbabilisticScorerDecodeErrorZ { + 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 = core::ptr::null_mut() }; + CResult_ProbabilisticScorerDecodeErrorZPtr { result } + } else { + let err = unsafe { o.contents.err }; + unsafe { o.contents.err = core::ptr::null_mut(); } + CResult_ProbabilisticScorerDecodeErrorZPtr { err } + }; + Self { + contents, + result_ok: o.result_ok, + } + } +} +#[repr(C)] /// The contents of CResult_InitFeaturesDecodeErrorZ pub union CResult_InitFeaturesDecodeErrorZPtr { /// A pointer to the contents in the success state. @@ -5104,6 +5230,23 @@ impl From> for CResu } } } +impl Clone for CResult_SecretKeyNoneZ { + fn clone(&self) -> Self { + if self.result_ok { + Self { result_ok: true, contents: CResult_SecretKeyNoneZPtr { + result: Box::into_raw(Box::new(::clone(unsafe { &*self.contents.result }))) + } } + } else { + Self { result_ok: false, contents: CResult_SecretKeyNoneZPtr { + err: core::ptr::null_mut() + } } + } + } +} +#[no_mangle] +/// Creates a new CResult_SecretKeyNoneZ which has the same data as `orig` +/// but with all dynamically-allocated buffers duplicated in new buffers. +pub extern "C" fn CResult_SecretKeyNoneZ_clone(orig: &CResult_SecretKeyNoneZ) -> CResult_SecretKeyNoneZ { Clone::clone(&orig) } #[repr(C)] /// The contents of CResult_SignDecodeErrorZ pub union CResult_SignDecodeErrorZPtr { diff --git a/lightning-c-bindings/src/lightning/routing/scoring.rs b/lightning-c-bindings/src/lightning/routing/scoring.rs index 31676d0..b526a78 100644 --- a/lightning-c-bindings/src/lightning/routing/scoring.rs +++ b/lightning-c-bindings/src/lightning/routing/scoring.rs @@ -707,6 +707,78 @@ pub extern "C" fn Scorer_read(ser: crate::c_types::u8slice) -> crate::c_types::d local_res } +use lightning::routing::scoring::ProbabilisticScorer as nativeProbabilisticScorerImport; +pub(crate) type nativeProbabilisticScorer = nativeProbabilisticScorerImport<&'static lightning::routing::network_graph::NetworkGraph>; + +/// [`Score`] implementation using channel success probability distributions. +/// +/// Based on *Optimally Reliable & Cheap Payment Flows on the Lightning Network* by Rene Pickhardt +/// and Stefan Richter [[1]]. Given the uncertainty of channel liquidity balances, probability +/// distributions are defined based on knowledge learned from successful and unsuccessful attempts. +/// Then the negative `log10` of the success probability is used to determine the cost of routing a +/// specific HTLC amount through a channel. +/// +/// Knowledge about channel liquidity balances takes the form of upper and lower bounds on the +/// possible liquidity. Certainty of the bounds is decreased over time using a decay function. See +/// [`ProbabilisticScoringParameters`] for details. +/// +/// Since the scorer aims to learn the current channel liquidity balances, it works best for nodes +/// with high payment volume or that actively probe the [`NetworkGraph`]. Nodes with low payment +/// volume are more likely to experience failed payment paths, which would need to be retried. +/// +/// # Note +/// +/// Mixing the `no-std` feature between serialization and deserialization results in undefined +/// behavior. +/// +/// [1]: https://arxiv.org/abs/2107.05322 +#[must_use] +#[repr(C)] +pub struct ProbabilisticScorer { + /// A pointer to the opaque Rust object. + + /// Nearly everywhere, inner must be non-null, however in places where + /// the Rust equivalent takes an Option, it may be set to null to indicate None. + pub inner: *mut nativeProbabilisticScorer, + /// Indicates that this is the only struct which contains the same pointer. + + /// Rust functions which take ownership of an object provided via an argument require + /// this to be true and invalidate the object pointed to by inner. + pub is_owned: bool, +} + +impl Drop for ProbabilisticScorer { + fn drop(&mut self) { + if self.is_owned && !<*mut nativeProbabilisticScorer>::is_null(self.inner) { + let _ = unsafe { Box::from_raw(ObjOps::untweak_ptr(self.inner)) }; + } + } +} +/// Frees any resources used by the ProbabilisticScorer, if is_owned is set and inner is non-NULL. +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_free(this_obj: ProbabilisticScorer) { } +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn ProbabilisticScorer_free_void(this_ptr: *mut c_void) { + unsafe { let _ = Box::from_raw(this_ptr as *mut nativeProbabilisticScorer); } +} +#[allow(unused)] +impl ProbabilisticScorer { + pub(crate) fn get_native_ref(&self) -> &'static nativeProbabilisticScorer { + unsafe { &*ObjOps::untweak_ptr(self.inner) } + } + pub(crate) fn get_native_mut_ref(&self) -> &'static mut nativeProbabilisticScorer { + unsafe { &mut *ObjOps::untweak_ptr(self.inner) } + } + /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy + pub(crate) fn take_inner(mut self) -> *mut nativeProbabilisticScorer { + assert!(self.is_owned); + let ret = ObjOps::untweak_ptr(self.inner); + self.inner = core::ptr::null_mut(); + ret + } +} + use lightning::routing::scoring::ProbabilisticScoringParameters as nativeProbabilisticScoringParametersImport; pub(crate) type nativeProbabilisticScoringParameters = nativeProbabilisticScoringParametersImport; @@ -871,12 +943,77 @@ pub extern "C" fn ProbabilisticScoringParameters_read(ser: crate::c_types::u8sli let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::routing::scoring::ProbabilisticScoringParameters { inner: ObjOps::heap_alloc(o), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: ObjOps::heap_alloc(e), is_owned: true } }).into() }; local_res } +/// Creates a new scorer using the given scoring parameters for sending payments from a node +/// through a network graph. +#[must_use] +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_new(mut params: crate::lightning::routing::scoring::ProbabilisticScoringParameters, network_graph: &crate::lightning::routing::network_graph::NetworkGraph) -> ProbabilisticScorer { + let mut ret = lightning::routing::scoring::ProbabilisticScorer::new(*unsafe { Box::from_raw(params.take_inner()) }, network_graph.get_native_ref()); + ProbabilisticScorer { inner: ObjOps::heap_alloc(ret), is_owned: true } +} + /// Creates a "default" ProbabilisticScoringParameters. See struct and individual field documentaiton for details on which values are used. #[must_use] #[no_mangle] pub extern "C" fn ProbabilisticScoringParameters_default() -> ProbabilisticScoringParameters { ProbabilisticScoringParameters { inner: ObjOps::heap_alloc(Default::default()), is_owned: true } } +impl From for crate::lightning::routing::scoring::Score { + fn from(obj: nativeProbabilisticScorer) -> Self { + let mut rust_obj = ProbabilisticScorer { inner: ObjOps::heap_alloc(obj), is_owned: true }; + let mut ret = ProbabilisticScorer_as_Score(&rust_obj); + // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn + rust_obj.inner = core::ptr::null_mut(); + ret.free = Some(ProbabilisticScorer_free_void); + ret + } +} +/// Constructs a new Score which calls the relevant methods on this_arg. +/// This copies the `inner` pointer in this_arg and thus the returned Score must be freed before this_arg is +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_as_Score(this_arg: &ProbabilisticScorer) -> crate::lightning::routing::scoring::Score { + crate::lightning::routing::scoring::Score { + this_arg: unsafe { ObjOps::untweak_ptr((*this_arg).inner) as *mut c_void }, + free: None, + channel_penalty_msat: ProbabilisticScorer_Score_channel_penalty_msat, + payment_path_failed: ProbabilisticScorer_Score_payment_path_failed, + payment_path_successful: ProbabilisticScorer_Score_payment_path_successful, + write: ProbabilisticScorer_write_void, + } +} + +#[must_use] +extern "C" fn ProbabilisticScorer_Score_channel_penalty_msat(this_arg: *const c_void, mut short_channel_id: u64, mut amount_msat: u64, mut capacity_msat: u64, source: &crate::lightning::routing::network_graph::NodeId, target: &crate::lightning::routing::network_graph::NodeId) -> u64 { + let mut ret = >::channel_penalty_msat(unsafe { &mut *(this_arg as *mut nativeProbabilisticScorer) }, short_channel_id, amount_msat, capacity_msat, source.get_native_ref(), target.get_native_ref()); + ret +} +extern "C" fn ProbabilisticScorer_Score_payment_path_failed(this_arg: *mut c_void, mut path: crate::c_types::derived::CVec_RouteHopZ, mut short_channel_id: u64) { + let mut local_path = Vec::new(); for mut item in path.as_slice().iter() { local_path.push( { item.get_native_ref() }); }; + >::payment_path_failed(unsafe { &mut *(this_arg as *mut nativeProbabilisticScorer) }, &local_path[..], short_channel_id) +} +extern "C" fn ProbabilisticScorer_Score_payment_path_successful(this_arg: *mut c_void, mut path: crate::c_types::derived::CVec_RouteHopZ) { + let mut local_path = Vec::new(); for mut item in path.as_slice().iter() { local_path.push( { item.get_native_ref() }); }; + >::payment_path_successful(unsafe { &mut *(this_arg as *mut nativeProbabilisticScorer) }, &local_path[..]) +} + +#[no_mangle] +/// Serialize the ProbabilisticScorer object into a byte array which can be read by ProbabilisticScorer_read +pub extern "C" fn ProbabilisticScorer_write(obj: &ProbabilisticScorer) -> crate::c_types::derived::CVec_u8Z { + crate::c_types::serialize_obj(unsafe { &*obj }.get_native_ref()) +} +#[no_mangle] +pub(crate) extern "C" fn ProbabilisticScorer_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z { + crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeProbabilisticScorer) }) +} +#[no_mangle] +/// Read a ProbabilisticScorer from a byte array, created by ProbabilisticScorer_write +pub extern "C" fn ProbabilisticScorer_read(ser: crate::c_types::u8slice, arg: crate::c_types::derived::C2Tuple_ProbabilisticScoringParametersNetworkGraphZ) -> crate::c_types::derived::CResult_ProbabilisticScorerDecodeErrorZ { + let (mut orig_arg_0, mut orig_arg_1) = arg.to_rust(); let mut local_arg = (*unsafe { Box::from_raw(orig_arg_0.take_inner()) }, orig_arg_1.get_native_ref()); + let arg_conv = local_arg; + let res: Result, lightning::ln::msgs::DecodeError> = crate::c_types::deserialize_obj_arg(ser, arg_conv); + let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::routing::scoring::ProbabilisticScorer { inner: ObjOps::heap_alloc(o), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: ObjOps::heap_alloc(e), is_owned: true } }).into() }; + local_res +} mod time { use alloc::str::FromStr;