From: Matt Corallo <649246+TheBlueMatt@users.noreply.github.com> Date: Thu, 22 Apr 2021 15:27:11 +0000 (+0000) Subject: Merge pull request #14 from TheBlueMatt/main X-Git-Tag: v0.0.98~13 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-c-bindings;a=commitdiff_plain;h=99d22ba053fc347d8116572f20ef1431fc05dee9;hp=1ea51d14faf91619495778e82bca2e6fad0ae1ae Merge pull request #14 from TheBlueMatt/main Update to latest upstream --- diff --git a/c-bindings-gen/Cargo.toml b/c-bindings-gen/Cargo.toml index dedeade..d963e43 100644 --- a/c-bindings-gen/Cargo.toml +++ b/c-bindings-gen/Cargo.toml @@ -9,6 +9,10 @@ syn = { version = "1", features = ["full", "extra-traits"] } proc-macro2 = "1" [profile.release] +incremental = true +codegen-units = 256 +opt-level = 2 +lto = false debug = true # We're not in the workspace as we're just a binary code generator: diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 7e4eee3..80ad2af 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -780,10 +780,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some("u64"), "std::io::Error" => Some("crate::c_types::IOError"), - "bitcoin::secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some("crate::c_types::PublicKey"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("*const [u8; 32]"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some("crate::c_types::SecretKey"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("*const [u8; 32]"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some("crate::c_types::SecretKey"), "bitcoin::secp256k1::Error" if !is_ref => Some("crate::c_types::Secp256k1Error"), "bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice"), "bitcoin::blockdata::script::Script" if !is_ref => Some("crate::c_types::derived::CVec_u8Z"), @@ -844,12 +847,16 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some("std::time::Duration::from_secs("), - "bitcoin::secp256k1::key::PublicKey" if is_ref => Some("&"), - "bitcoin::secp256k1::key::PublicKey" => Some(""), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + if is_ref => Some("&"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(""), "bitcoin::secp256k1::Signature" if is_ref => Some("&"), "bitcoin::secp256k1::Signature" => Some(""), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(""), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(""), "bitcoin::blockdata::script::Script" if is_ref => Some("&::bitcoin::blockdata::script::Script::from(Vec::from("), "bitcoin::blockdata::script::Script" if !is_ref => Some("::bitcoin::blockdata::script::Script::from("), "bitcoin::blockdata::transaction::Transaction" if is_ref => Some("&"), @@ -899,10 +906,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some(")"), - "bitcoin::secp256k1::key::PublicKey" => Some(".into_rust()"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(".into_rust()"), "bitcoin::secp256k1::Signature" => Some(".into_rust()"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(".into_rust()"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("}[..]).unwrap()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(".into_rust()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("}[..]).unwrap()"), "bitcoin::blockdata::script::Script" if is_ref => Some(".to_slice()))"), "bitcoin::blockdata::script::Script" if !is_ref => Some(".into_rust())"), "bitcoin::blockdata::transaction::Transaction" => Some(".into_bitcoin()"), @@ -973,10 +983,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some(""), "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("), - "bitcoin::secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey::from_rust(&"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some("crate::c_types::PublicKey::from_rust(&"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature::from_rust(&"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some(""), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some("crate::c_types::SecretKey::from_rust("), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some(""), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some("crate::c_types::SecretKey::from_rust("), "bitcoin::secp256k1::Error" if !is_ref => Some("crate::c_types::Secp256k1Error::from_rust("), "bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice::from_slice(&"), "bitcoin::blockdata::script::Script" if !is_ref => Some(""), @@ -1032,10 +1045,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some(".as_secs()"), "std::io::Error" if !is_ref => Some(")"), - "bitcoin::secp256k1::key::PublicKey" => Some(")"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(")"), "bitcoin::secp256k1::Signature" => Some(")"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(")"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some(".as_ref()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(")"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some(".as_ref()"), "bitcoin::secp256k1::Error" if !is_ref => Some(")"), "bitcoin::blockdata::script::Script" if is_ref => Some("[..])"), "bitcoin::blockdata::script::Script" if !is_ref => Some(".into_bytes().into()"), diff --git a/genbindings.sh b/genbindings.sh index a5c6bc1..8fd1188 100755 --- a/genbindings.sh +++ b/genbindings.sh @@ -247,7 +247,7 @@ if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then export CFLAGS_wasm32_wasi="-target wasm32" fi -if [ "$(rustc --print target-list | grep wasm32-wasi)" != "" ]; then +if [ "$2" = "false" -a "$(rustc --print target-list | grep wasm32-wasi)" != "" ]; then # Test to see if clang supports wasm32 as a target (which is needed to build rust-secp256k1) echo "int main() {}" > genbindings_wasm_test_file.c clang -nostdlib -o /dev/null --target=wasm32-wasi -Wl,--no-entry genbindings_wasm_test_file.c > /dev/null 2>&1 && @@ -271,7 +271,11 @@ if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then # or Ubuntu packages). This should work fine on Distros which do more involved # packaging than simply shipping the rustup binaries (eg Debian should Just Work # here). - export CFLAGS="$CFLAGS -flto" + # The cc-rs crate tries to force -fdata-sections and -ffunction-sections on, which + # breaks -fembed-bitcode, so we turn off cc-rs' default flags and specify exactly + # what we want here. + export CFLAGS="$CFLAGS -O3 -fPIC -fembed-bitcode" + export CRATE_CC_NO_DEFAULTS=true # Rust doesn't recognize CFLAGS changes, so we need to clean build artifacts cargo clean --release CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C linker-plugin-lto -C lto -C link-arg=-fuse-ld=lld diff --git a/lightning-c-bindings/Cargo.toml b/lightning-c-bindings/Cargo.toml index e764b7e..f3f75b0 100644 --- a/lightning-c-bindings/Cargo.toml +++ b/lightning-c-bindings/Cargo.toml @@ -18,8 +18,8 @@ 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 = "52f1d45bb20114bf89880e8128d0f570e426f0a6", features = ["allow_wallclock_use"] } -lightning-persister = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "52f1d45bb20114bf89880e8128d0f570e426f0a6" } +lightning = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "f40e47c1ef6957ab548345162ffbd540bc7fe0a2", features = ["allow_wallclock_use"] } +lightning-persister = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "f40e47c1ef6957ab548345162ffbd540bc7fe0a2" } [patch.crates-io] # Rust-Secp256k1 PR 279. Should be dropped once merged. diff --git a/lightning-c-bindings/cbindgen.toml b/lightning-c-bindings/cbindgen.toml index 9480b86..b9e49b3 100644 --- a/lightning-c-bindings/cbindgen.toml +++ b/lightning-c-bindings/cbindgen.toml @@ -1,555 +1,30 @@ -# The language to output bindings in -# -# possible values: "C", "C++" -# -# default: "C++" language = "C" - - - - -# Options for wrapping the contents of the header: - -# An optional string of text to output at the beginning of the generated file -# default: doesn't emit anything -header = "/* Text to put at the beginning of the generated file. Probably a license. */" - -# An optional string of text to output at the end of the generated file -# default: doesn't emit anything -trailer = "/* Text to put at the end of the generated file */" - -# An optional name to use as an include guard -# default: doesn't emit an include guard -# include_guard = "mozilla_wr_bindings_h" - -# An optional string of text to output between major sections of the generated -# file as a warning against manual editing -# -# default: doesn't emit anything +include_guard = "LDK_C_BINDINGS_H" autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */" - -# Whether to include a comment with the version of cbindgen used to generate the file -# default: false include_version = true - -# An optional namespace to output around the generated bindings -# default: doesn't emit a namespace namespace = "LDK" -# An optional list of namespaces to output around the generated bindings -# default: [] -namespaces = [] - -# An optional list of namespaces to declare as using with "using namespace" -# default: [] -using_namespaces = [] - -# A list of sys headers to #include (with angle brackets) -# default: [] -# sys_includes = ["stdio", "string"] -# sys_includes = ["stdint"] - -# A list of headers to #include (with quotes) -# default: [] -# includes = ["my_great_lib.h"] - -# Whether cbindgen's default C/C++ standard imports should be suppressed. These -# imports are included by default because our generated headers tend to require -# them (e.g. for uint32_t). Currently, the generated imports are: -# -# * for C: , , , , -# -# * for C++: , , , , (depending on config) -# -# default: false -no_includes = false - - - - - -# Code Style Options - -# The style to use for curly braces -# -# possible values: "SameLine", "NextLine" -# -# default: "SameLine" -braces = "SameLine" - -# The desired length of a line to use when formatting lines -# default: 100 line_length = 80 - -# The amount of spaces to indent by -# default: 2 tab_width = 3 -# How the generated documentation should be commented. -# -# possible values: -# * "c": /* like this */ -# * "c99": // like this -# * "c++": /// like this -# * "doxy": like C, but with leading *'s on each line -# * "auto": "c++" if that's the language, "doxy" otherwise -# -# default: "auto" -documentation_style = "doxy" - - - - - -# Codegen Options - -# When generating a C header, the kind of declaration style to use for structs -# or enums. -# -# possible values: -# * "type": typedef struct { ... } MyType; -# * "tag": struct MyType { ... }; -# * "both": typedef struct MyType { ... } MyType; -# -# default: "both" -style = "both" - -# A list of substitutions for converting cfg's to ifdefs. cfgs which aren't -# defined here will just be discarded. -# -# e.g. -# `#[cfg(target = "freebsd")] ...` -# becomes -# `#if defined(DEFINE_FREEBSD) ... #endif` -[defines] -"target_os = freebsd" = "DEFINE_FREEBSD" -"feature = serde" = "DEFINE_SERDE" - - - - - [export] -# A list of additional items to always include in the generated bindings if they're -# found but otherwise don't appear to be used by the public API. -# -# default: [] -# include = ["MyOrphanStruct", "MyGreatTypeRename"] - -# A list of items to not include in the generated bindings -# default: [] -# exclude = ["Bad"] - -# A prefix to add before the name of every item -# default: no prefix is added prefix = "LDK" -# Types of items that we'll generate. If empty, then all types of item are emitted. -# -# possible items: (TODO: explain these in detail) -# * "constants": -# * "globals": -# * "enums": -# * "structs": -# * "unions": -# * "typedefs": -# * "opaque": -# * "functions": -# -# default: [] -item_types = ["constants", "globals", "enums", "structs", "unions", "typedefs", "opaque", "functions"] - -# Whether applying rules in export.rename prevents export.prefix from applying. -# -# e.g. given this toml: -# -# [export] -# prefix = "capi_" -# [export.rename] -# "MyType" = "my_cool_type" -# -# You get the following results: -# -# renaming_overrides_prefixing = true: -# "MyType" => "my_cool_type" -# -# renaming_overrides_prefixing = false: -# "MyType => capi_my_cool_type" -# -# default: false -renaming_overrides_prefixing = true - -# Table of name conversions to apply to item names (lhs becomes rhs) -# [export.rename] -# "MyType" = "my_cool_type" -# "my_function" = "BetterFunctionName" - -# Table of things to prepend to the body of any struct, union, or enum that has the -# given name. This can be used to add things like methods which don't change ABI, -# mark fields private, etc -[export.pre_body] -"MyType" = """ - MyType() = delete; -private: -""" - -# Table of things to append to the body of any struct, union, or enum that has the -# given name. This can be used to add things like methods which don't change ABI. -[export.body] -"MyType" = """ - void cppMethod() const; -""" - -[layout] -# A string that should come before the name of any type which has been marked -# as `#[repr(packed)]`. For instance, "__attribute__((packed))" would be a -# reasonable value if targeting gcc/clang. A more portable solution would -# involve emitting the name of a macro which you define in a platform-specific -# way. e.g. "PACKED" -# -# default: `#[repr(packed)]` types will be treated as opaque, since it would -# be unsafe for C callers to use a incorrectly laid-out union. -packed = "PACKED" - -# A string that should come before the name of any type which has been marked -# as `#[repr(align(n))]`. This string must be a function-like macro which takes -# a single argument (the requested alignment, `n`). For instance, a macro -# `#define`d as `ALIGNED(n)` in `header` which translates to -# `__attribute__((aligned(n)))` would be a reasonable value if targeting -# gcc/clang. -# -# default: `#[repr(align(n))]` types will be treated as opaque, since it -# could be unsafe for C callers to use a incorrectly-aligned union. -aligned_n = "ALIGNED" - - [fn] -# An optional prefix to put before every function declaration -# default: no prefix added -# prefix = "WR_START_FUNC" - -# An optional postfix to put after any function declaration -# default: no postix added -# postfix = "WR_END_FUNC" - -# How to format function arguments -# -# possible values: -# * "horizontal": place all arguments on the same line -# * "vertical": place each argument on its own line -# * "auto": only use vertical if horizontal would exceed line_length -# -# default: "auto" args = "horizontal" - -# An optional string that should prefix function declarations which have been -# marked as `#[must_use]`. For instance, "__attribute__((warn_unused_result))" -# would be a reasonable value if targeting gcc/clang. A more portable solution -# would involve emitting the name of a macro which you define in a -# platform-specific way. e.g. "MUST_USE_FUNC" -# default: nothing is emitted for must_use functions must_use = "MUST_USE_RES" -# An optional string that, if present, will be used to generate Swift function -# and method signatures for generated functions, for example "CF_SWIFT_NAME". -# If no such macro is available in your toolchain, you can define one using the -# `header` option in cbindgen.toml -# default: no swift_name function attributes are generated -# swift_name_macro = "CF_SWIFT_NAME" - -# A rule to use to rename function argument names. The renaming assumes the input -# is the Rust standard snake_case, however it accepts all the different rename_args -# inputs. This means many options here are no-ops or redundant. -# -# possible values (that actually do something): -# * "CamelCase": my_arg => myArg -# * "PascalCase": my_arg => MyArg -# * "GeckoCase": my_arg => aMyArg -# * "ScreamingSnakeCase": my_arg => MY_ARG -# * "None": apply no renaming -# -# technically possible values (that shouldn't have a purpose here): -# * "SnakeCase": apply no renaming -# * "LowerCase": apply no renaming (actually applies to_lowercase, is this bug?) -# * "UpperCase": same as ScreamingSnakeCase in this context -# * "QualifiedScreamingSnakeCase" => same as ScreamingSnakeCase in this context -# -# default: "None" -rename_args = "None" - -# This rule specifies if the order of functions will be sorted in some way. -# -# "Name": sort by the name of the function -# "None": keep order in which the functions have been parsed -# -# default: "Name" -sort_by = "None" - [struct] -# A rule to use to rename struct field names. The renaming assumes the input is -# the Rust standard snake_case, however it acccepts all the different rename_args -# inputs. This means many options here are no-ops or redundant. -# -# possible values (that actually do something): -# * "CamelCase": my_arg => myArg -# * "PascalCase": my_arg => MyArg -# * "GeckoCase": my_arg => mMyArg -# * "ScreamingSnakeCase": my_arg => MY_ARG -# * "None": apply no renaming -# -# technically possible values (that shouldn't have a purpose here): -# * "SnakeCase": apply no renaming -# * "LowerCase": apply no renaming (actually applies to_lowercase, is this bug?) -# * "UpperCase": same as ScreamingSnakeCase in this context -# * "QualifiedScreamingSnakeCase" => same as ScreamingSnakeCase in this context -# -# default: "None" -rename_fields = "None" - -# An optional string that should come before the name of any struct which has been -# marked as `#[must_use]`. For instance, "__attribute__((warn_unused))" -# would be a reasonable value if targeting gcc/clang. A more portable solution -# would involve emitting the name of a macro which you define in a -# platform-specific way. e.g. "MUST_USE_STRUCT" -# -# default: nothing is emitted for must_use structs must_use = "MUST_USE_STRUCT" -# Whether a Rust type with associated consts should emit those consts inside the -# type's body. Otherwise they will be emitted trailing and with the type's name -# prefixed. This does nothing if the target is C, or if -# [const]allow_static_const = false -# -# default: false -# associated_constants_in_body: false - -# Whether to derive a simple constructor that takes a value for every field. -# default: false -derive_constructor = true - -# Whether to derive an operator== for all structs -# default: false -derive_eq = false - -# Whether to derive an operator!= for all structs -# default: false -derive_neq = false - -# Whether to derive an operator< for all structs -# default: false -derive_lt = false - -# Whether to derive an operator<= for all structs -# default: false -derive_lte = false - -# Whether to derive an operator> for all structs -# default: false -derive_gt = false - -# Whether to derive an operator>= for all structs -# default: false -derive_gte = false - - - - - [enum] -# A rule to use to rename enum variants, and the names of any fields those -# variants have. This should probably be split up into two separate options, but -# for now, they're the same! See the documentation for `[struct]rename_fields` -# for how this applies to fields. Renaming of the variant assumes that the input -# is the Rust standard PascalCase. In the case of QualifiedScreamingSnakeCase, -# it also assumed that the enum's name is PascalCase. -# -# possible values (that actually do something): -# * "CamelCase": MyVariant => myVariant -# * "SnakeCase": MyVariant => my_variant -# * "ScreamingSnakeCase": MyVariant => MY_VARIANT -# * "QualifiedScreamingSnakeCase": MyVariant => ENUM_NAME_MY_VARIANT -# * "LowerCase": MyVariant => myvariant -# * "UpperCase": MyVariant => MYVARIANT -# * "None": apply no renaming -# -# technically possible values (that shouldn't have a purpose for the variants): -# * "PascalCase": apply no renaming -# * "GeckoCase": apply no renaming -# -# default: "None" -rename_variants = "None" - -# Whether an extra "sentinel" enum variant should be added to all generated enums. -# Firefox uses this for their IPC serialization library. -# -# WARNING: if the sentinel is ever passed into Rust, behaviour will be Undefined. -# Rust does not know about this value, and will assume it cannot happen. -# -# default: false +# We use the sentinel as a flag to indicate memory freeing is not necessary. add_sentinel = true # Whether enum variant names should be prefixed with the name of the enum. # default: false prefix_with_name = true - -# Whether to emit enums using "enum class" when targeting C++. -# default: true -enum_class = true - -# Whether to generate static `::MyVariant(..)` constructors and `bool IsMyVariant()` -# methods for enums with fields. -# -# default: false -derive_helper_methods = false - -# Whether to generate `const MyVariant& AsMyVariant() const` methods for enums with fields. -# default: false -derive_const_casts = false - -# Whether to generate `MyVariant& AsMyVariant()` methods for enums with fields -# default: false -derive_mut_casts = false - -# The name of the macro/function to use for asserting `IsMyVariant()` in the body of -# derived `AsMyVariant()` cast methods. -# -# default: "assert" (but also causes `` to be included by default) -cast_assert_name = "MOZ_RELEASE_ASSERT" - -# An optional string that should come before the name of any enum which has been -# marked as `#[must_use]`. For instance, "__attribute__((warn_unused))" -# would be a reasonable value if targeting gcc/clang. A more portable solution -# would involve emitting the name of a macro which you define in a -# platform-specific way. e.g. "MUST_USE_ENUM" -# -# Note that this refers to the *output* type. That means this will not apply to an enum -# with fields, as it will be emitted as a struct. `[struct]must_use` will apply there. -# -# default: nothing is emitted for must_use enums must_use = "MUST_USE_ENUM" -# Whether enums with fields should generate destructors. This exists so that generic -# enums can be properly instantiated with payloads that are C++ types with -# destructors. This isn't necessary for structs because C++ has rules to -# automatically derive the correct constructors and destructors for those types. -# -# Care should be taken with this option, as Rust and C++ cannot -# properly interoperate with eachother's notions of destructors. Also, this may -# change the ABI for the type. Either your destructor-full enums must live -# exclusively within C++, or they must only be passed by-reference between -# C++ and Rust. -# -# default: false -derive_tagged_enum_destructor = false - -# Whether enums with fields should generate copy-constructor. See the discussion on -# derive_tagged_enum_destructor for why this is both useful and very dangerous. -# -# default: false -derive_tagged_enum_copy_constructor = false -# Whether enums with fields should generate copy-assignment operators. -# -# This depends on also deriving copy-constructors, and it is highly encouraged -# for this to be set to true. -# -# default: false -derive_tagged_enum_copy_assignment = false - -# Whether enums with fields should generate an empty, private destructor. -# This allows the auto-generated constructor functions to compile, if there are -# non-trivially constructible members. This falls in the same family of -# dangerousness as `derive_tagged_enum_copy_constructor` and co. -# -# default: false -private_default_tagged_enum_constructor = false - - - - - -[const] -# Whether a generated constant can be a static const in C++ mode. I have no -# idea why you would turn this off. -# -# default: true -allow_static_const = true - -# Whether a generated constant can be constexpr in C++ mode. -# -# default: false - - - - - -[macro_expansion] -# Whether bindings should be generated for instances of the bitflags! macro. -# default: false -bitflags = true - - - - - - -# Options for how your Rust library should be parsed - -[parse] -# Whether to parse dependent crates and include their types in the output -# default: false -parse_deps = true - -# A white list of crate names that are allowed to be parsed. If this is defined, -# only crates found in this list will ever be parsed. -# -# default: there is no whitelist (NOTE: this is the opposite of []) -include = ["webrender", "webrender_traits"] - -# A black list of crate names that are not allowed to be parsed. -# default: [] -exclude = ["libc"] - -# Whether to use a new temporary target directory when running `rustc --pretty=expanded`. -# This may be required for some build processes. -# -# default: false -clean = false - -# Which crates other than the top-level binding crate we should generate -# bindings for. -# -# default: [] -extra_bindings = ["my_awesome_dep"] - -[parse.expand] -# A list of crate names that should be run through `cargo expand` before -# parsing to expand any macros. Note that if a crate is named here, it -# will always be parsed, even if the blacklist/whitelist says it shouldn't be. -# -# default: [] -crates = ["euclid"] - -# If enabled, use the `--all-features` option when expanding. Ignored when -# `features` is set. For backwards-compatibility, this is forced on if -# `expand = ["euclid"]` shorthand is used. -# -# default: false -all_features = false - -# When `all_features` is disabled and this is also disabled, use the -# `--no-default-features` option when expanding. -# -# default: true -default_features = true - -# A list of feature names that should be used when running `cargo expand`. This -# combines with `default_features` like in your `Cargo.toml`. Note that the features -# listed here are features for the current crate being built, *not* the crates -# being expanded. The crate's `Cargo.toml` must take care of enabling the -# appropriate features in its dependencies -# -# default: [] -features = ["cbindgen"] - [ptr] non_null_attribute = "NONNULL_PTR" diff --git a/lightning-c-bindings/demo.cpp b/lightning-c-bindings/demo.cpp index e0827f6..cee3054 100644 --- a/lightning-c-bindings/demo.cpp +++ b/lightning-c-bindings/demo.cpp @@ -510,7 +510,7 @@ int main() { 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_RouteHintZ { + }, &outbound_channels, LDKCVec_RouteHintHopZ { .data = NULL, .datalen = 0 }, 5000, 10, logger1); assert(route->result_ok); diff --git a/lightning-c-bindings/include/lightning.h b/lightning-c-bindings/include/lightning.h index a6b73a5..7d09159 100644 --- a/lightning-c-bindings/include/lightning.h +++ b/lightning-c-bindings/include/lightning.h @@ -1,4 +1,5 @@ -/* Text to put at the beginning of the generated file. Probably a license. */ +#ifndef LDK_C_BINDINGS_H +#define LDK_C_BINDINGS_H /* Generated with cbindgen:0.16.0 */ @@ -1153,6 +1154,39 @@ typedef struct LDKCResult_CVec_SignatureZNoneZ { bool result_ok; } LDKCResult_CVec_SignatureZNoneZ; +/** + * The contents of CResult_StringErrorZ + */ +typedef union LDKCResult_StringErrorZPtr { + /** + * A pointer to the contents in the success state. + * Reading from this pointer when `result_ok` is not set is undefined. + */ + struct LDKCVec_u8Z *result; + /** + * A pointer to the contents in the error state. + * Reading from this pointer when `result_ok` is set is undefined. + */ + enum LDKSecp256k1Error *err; +} LDKCResult_StringErrorZPtr; + +/** + * A CResult_StringErrorZ represents the result of a fallible operation, + * containing a crate::c_types::derived::CVec_u8Z on success and a crate::c_types::Secp256k1Error on failure. + * `result_ok` indicates the overall state, and the contents are provided via `contents`. + */ +typedef struct LDKCResult_StringErrorZ { + /** + * The contents of this CResult_StringErrorZ, accessible via either + * `err` or `result` depending on the state of `result_ok`. + */ + union LDKCResult_StringErrorZPtr contents; + /** + * Whether this CResult_StringErrorZ represents a success state. + */ + bool result_ok; +} LDKCResult_StringErrorZ; + /** @@ -2469,36 +2503,36 @@ typedef struct LDKCVec_ChannelDetailsZ { /** * A channel descriptor which provides a last-hop route to get_route */ -typedef struct MUST_USE_STRUCT LDKRouteHint { +typedef struct MUST_USE_STRUCT LDKRouteHintHop { /** * 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. */ - LDKnativeRouteHint *inner; + LDKnativeRouteHintHop *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; -} LDKRouteHint; +} LDKRouteHintHop; /** - * A dynamically-allocated array of crate::lightning::routing::router::RouteHints of arbitrary size. + * A dynamically-allocated array of crate::lightning::routing::router::RouteHintHops of arbitrary size. * This corresponds to std::vector in C++ */ -typedef struct LDKCVec_RouteHintZ { +typedef struct LDKCVec_RouteHintHopZ { /** * The elements in the array. * If datalen is non-0 this must be a valid, non-NULL pointer allocated by malloc(). */ - struct LDKRouteHint *data; + struct LDKRouteHintHop *data; /** * The number of elements pointed to by `data`. */ uintptr_t datalen; -} LDKCVec_RouteHintZ; +} LDKCVec_RouteHintHopZ; @@ -7957,6 +7991,21 @@ void CResult_CVec_SignatureZNoneZ_free(struct LDKCResult_CVec_SignatureZNoneZ _r */ struct LDKCResult_CVec_SignatureZNoneZ CResult_CVec_SignatureZNoneZ_clone(const struct LDKCResult_CVec_SignatureZNoneZ *NONNULL_PTR orig); +/** + * Creates a new CResult_StringErrorZ in the success state. + */ +struct LDKCResult_StringErrorZ CResult_StringErrorZ_ok(struct LDKCVec_u8Z o); + +/** + * Creates a new CResult_StringErrorZ in the error state. + */ +struct LDKCResult_StringErrorZ CResult_StringErrorZ_err(enum LDKSecp256k1Error e); + +/** + * Frees any resources used by the CResult_StringErrorZ. + */ +void CResult_StringErrorZ_free(struct LDKCResult_StringErrorZ _res); + /** * Creates a new CResult_ChannelMonitorUpdateDecodeErrorZ in the success state. */ @@ -8237,7 +8286,7 @@ void CVec_ChannelDetailsZ_free(struct LDKCVec_ChannelDetailsZ _res); /** * Frees the buffer pointed to by `data` if `datalen` is non-0. */ -void CVec_RouteHintZ_free(struct LDKCVec_RouteHintZ _res); +void CVec_RouteHintHopZ_free(struct LDKCVec_RouteHintHopZ _res); /** * Creates a new CResult_RouteLightningErrorZ in the success state. @@ -9685,6 +9734,24 @@ void APIError_free(struct LDKAPIError this_ptr); */ struct LDKAPIError APIError_clone(const struct LDKAPIError *NONNULL_PTR orig); +/** + * Creates a digital signature of a message given a SecretKey, like the node's secret. + * A receiver knowing the PublicKey (e.g. the node's id) and the message can be sure that the signature was generated by the caller. + * Signatures are EC recoverable, meaning that given the message and the signature the PublicKey of the signer can be extracted. + */ +struct LDKCResult_StringErrorZ sign(struct LDKu8slice msg, struct LDKSecretKey sk); + +/** + * Recovers the PublicKey of the signer of the message given the message and the signature. + */ +struct LDKCResult_PublicKeyErrorZ recover_pk(struct LDKu8slice msg, struct LDKStr sig); + +/** + * Verifies a message was signed by a PrivateKey that derives to a given PublicKey, given a message, a signature, + * and the PublicKey. + */ +bool verify(struct LDKu8slice msg, struct LDKStr sig, struct LDKPublicKey pk); + /** * Creates a copy of the Level */ @@ -15114,79 +15181,79 @@ struct LDKCVec_u8Z Route_write(const struct LDKRoute *NONNULL_PTR obj); struct LDKCResult_RouteDecodeErrorZ Route_read(struct LDKu8slice ser); /** - * Frees any resources used by the RouteHint, if is_owned is set and inner is non-NULL. + * Frees any resources used by the RouteHintHop, if is_owned is set and inner is non-NULL. */ -void RouteHint_free(struct LDKRouteHint this_obj); +void RouteHintHop_free(struct LDKRouteHintHop this_obj); /** * The node_id of the non-target end of the route */ -struct LDKPublicKey RouteHint_get_src_node_id(const struct LDKRouteHint *NONNULL_PTR this_ptr); +struct LDKPublicKey RouteHintHop_get_src_node_id(const struct LDKRouteHintHop *NONNULL_PTR this_ptr); /** * The node_id of the non-target end of the route */ -void RouteHint_set_src_node_id(struct LDKRouteHint *NONNULL_PTR this_ptr, struct LDKPublicKey val); +void RouteHintHop_set_src_node_id(struct LDKRouteHintHop *NONNULL_PTR this_ptr, struct LDKPublicKey val); /** * The short_channel_id of this channel */ -uint64_t RouteHint_get_short_channel_id(const struct LDKRouteHint *NONNULL_PTR this_ptr); +uint64_t RouteHintHop_get_short_channel_id(const struct LDKRouteHintHop *NONNULL_PTR this_ptr); /** * The short_channel_id of this channel */ -void RouteHint_set_short_channel_id(struct LDKRouteHint *NONNULL_PTR this_ptr, uint64_t val); +void RouteHintHop_set_short_channel_id(struct LDKRouteHintHop *NONNULL_PTR this_ptr, uint64_t val); /** * The fees which must be paid to use this channel */ -struct LDKRoutingFees RouteHint_get_fees(const struct LDKRouteHint *NONNULL_PTR this_ptr); +struct LDKRoutingFees RouteHintHop_get_fees(const struct LDKRouteHintHop *NONNULL_PTR this_ptr); /** * The fees which must be paid to use this channel */ -void RouteHint_set_fees(struct LDKRouteHint *NONNULL_PTR this_ptr, struct LDKRoutingFees val); +void RouteHintHop_set_fees(struct LDKRouteHintHop *NONNULL_PTR this_ptr, struct LDKRoutingFees val); /** * The difference in CLTV values between this node and the next node. */ -uint16_t RouteHint_get_cltv_expiry_delta(const struct LDKRouteHint *NONNULL_PTR this_ptr); +uint16_t RouteHintHop_get_cltv_expiry_delta(const struct LDKRouteHintHop *NONNULL_PTR this_ptr); /** * The difference in CLTV values between this node and the next node. */ -void RouteHint_set_cltv_expiry_delta(struct LDKRouteHint *NONNULL_PTR this_ptr, uint16_t val); +void RouteHintHop_set_cltv_expiry_delta(struct LDKRouteHintHop *NONNULL_PTR this_ptr, uint16_t val); /** * The minimum value, in msat, which must be relayed to the next hop. */ -struct LDKCOption_u64Z RouteHint_get_htlc_minimum_msat(const struct LDKRouteHint *NONNULL_PTR this_ptr); +struct LDKCOption_u64Z RouteHintHop_get_htlc_minimum_msat(const struct LDKRouteHintHop *NONNULL_PTR this_ptr); /** * The minimum value, in msat, which must be relayed to the next hop. */ -void RouteHint_set_htlc_minimum_msat(struct LDKRouteHint *NONNULL_PTR this_ptr, struct LDKCOption_u64Z val); +void RouteHintHop_set_htlc_minimum_msat(struct LDKRouteHintHop *NONNULL_PTR this_ptr, struct LDKCOption_u64Z val); /** * The maximum value in msat available for routing with a single HTLC. */ -struct LDKCOption_u64Z RouteHint_get_htlc_maximum_msat(const struct LDKRouteHint *NONNULL_PTR this_ptr); +struct LDKCOption_u64Z RouteHintHop_get_htlc_maximum_msat(const struct LDKRouteHintHop *NONNULL_PTR this_ptr); /** * The maximum value in msat available for routing with a single HTLC. */ -void RouteHint_set_htlc_maximum_msat(struct LDKRouteHint *NONNULL_PTR this_ptr, struct LDKCOption_u64Z val); +void RouteHintHop_set_htlc_maximum_msat(struct LDKRouteHintHop *NONNULL_PTR this_ptr, struct LDKCOption_u64Z val); /** - * Constructs a new RouteHint given each field + * Constructs a new RouteHintHop given each field */ -MUST_USE_RES struct LDKRouteHint RouteHint_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); +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); /** - * Creates a copy of the RouteHint + * Creates a copy of the RouteHintHop */ -struct LDKRouteHint RouteHint_clone(const struct LDKRouteHint *NONNULL_PTR orig); +struct LDKRouteHintHop RouteHintHop_clone(const struct LDKRouteHintHop *NONNULL_PTR orig); /** * Gets a route from us (payer) to the given target node (payee). @@ -15209,7 +15276,7 @@ struct LDKRouteHint RouteHint_clone(const struct LDKRouteHint *NONNULL_PTR orig) * equal), however the enabled/disabled bit on such channels as well as the * htlc_minimum_msat/htlc_maximum_msat *are* checked as they may change based on the receiving node. */ -struct LDKCResult_RouteLightningErrorZ get_route(struct LDKPublicKey our_node_id, const struct LDKNetworkGraph *NONNULL_PTR network, struct LDKPublicKey payee, struct LDKInvoiceFeatures payee_features, struct LDKCVec_ChannelDetailsZ *first_hops, struct LDKCVec_RouteHintZ last_hops, uint64_t final_value_msat, uint32_t final_cltv, struct LDKLogger logger); +struct LDKCResult_RouteLightningErrorZ get_route(struct LDKPublicKey our_node_id, const struct LDKNetworkGraph *NONNULL_PTR network, struct LDKPublicKey payee, struct LDKInvoiceFeatures payee_features, struct LDKCVec_ChannelDetailsZ *first_hops, struct LDKCVec_RouteHintHopZ last_hops, uint64_t final_value_msat, uint32_t final_cltv, struct LDKLogger logger); /** * Frees any resources used by the NetworkGraph, if is_owned is set and inner is non-NULL. @@ -15792,4 +15859,4 @@ MUST_USE_RES struct LDKCResult_CVec_C2Tuple_BlockHashChannelMonitorZZErrorZ File */ struct LDKPersist FilesystemPersister_as_Persist(const struct LDKFilesystemPersister *NONNULL_PTR this_arg); -/* Text to put at the end of the generated file */ +#endif /* LDK_C_BINDINGS_H */ diff --git a/lightning-c-bindings/include/lightningpp.hpp b/lightning-c-bindings/include/lightningpp.hpp index b8795c7..a40d840 100644 --- a/lightning-c-bindings/include/lightningpp.hpp +++ b/lightning-c-bindings/include/lightningpp.hpp @@ -374,20 +374,20 @@ public: const LDKRoute* operator &() const { return &self; } const LDKRoute* operator ->() const { return &self; } }; -class RouteHint { +class RouteHintHop { private: - LDKRouteHint self; + LDKRouteHintHop self; public: - RouteHint(const RouteHint&) = delete; - RouteHint(RouteHint&& o) : self(o.self) { memset(&o, 0, sizeof(RouteHint)); } - RouteHint(LDKRouteHint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKRouteHint)); } - operator LDKRouteHint() && { LDKRouteHint res = self; memset(&self, 0, sizeof(LDKRouteHint)); return res; } - ~RouteHint() { RouteHint_free(self); } - RouteHint& operator=(RouteHint&& o) { RouteHint_free(self); self = o.self; memset(&o, 0, sizeof(RouteHint)); return *this; } - LDKRouteHint* operator &() { return &self; } - LDKRouteHint* operator ->() { return &self; } - const LDKRouteHint* operator &() const { return &self; } - const LDKRouteHint* operator ->() const { return &self; } + RouteHintHop(const RouteHintHop&) = delete; + RouteHintHop(RouteHintHop&& o) : self(o.self) { memset(&o, 0, sizeof(RouteHintHop)); } + RouteHintHop(LDKRouteHintHop&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKRouteHintHop)); } + operator LDKRouteHintHop() && { LDKRouteHintHop res = self; memset(&self, 0, sizeof(LDKRouteHintHop)); return res; } + ~RouteHintHop() { RouteHintHop_free(self); } + RouteHintHop& operator=(RouteHintHop&& o) { RouteHintHop_free(self); self = o.self; memset(&o, 0, sizeof(RouteHintHop)); return *this; } + LDKRouteHintHop* operator &() { return &self; } + LDKRouteHintHop* operator ->() { return &self; } + const LDKRouteHintHop* operator &() const { return &self; } + const LDKRouteHintHop* operator ->() const { return &self; } }; class IgnoringMessageHandler { private: @@ -2621,6 +2621,21 @@ public: const LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ* operator &() const { return &self; } const LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ* operator ->() const { return &self; } }; +class CVec_RouteHintHopZ { +private: + LDKCVec_RouteHintHopZ self; +public: + CVec_RouteHintHopZ(const CVec_RouteHintHopZ&) = delete; + CVec_RouteHintHopZ(CVec_RouteHintHopZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_RouteHintHopZ)); } + CVec_RouteHintHopZ(LDKCVec_RouteHintHopZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_RouteHintHopZ)); } + operator LDKCVec_RouteHintHopZ() && { LDKCVec_RouteHintHopZ res = self; memset(&self, 0, sizeof(LDKCVec_RouteHintHopZ)); return res; } + ~CVec_RouteHintHopZ() { CVec_RouteHintHopZ_free(self); } + CVec_RouteHintHopZ& operator=(CVec_RouteHintHopZ&& o) { CVec_RouteHintHopZ_free(self); self = o.self; memset(&o, 0, sizeof(CVec_RouteHintHopZ)); return *this; } + LDKCVec_RouteHintHopZ* operator &() { return &self; } + LDKCVec_RouteHintHopZ* operator ->() { return &self; } + const LDKCVec_RouteHintHopZ* operator &() const { return &self; } + const LDKCVec_RouteHintHopZ* operator ->() const { return &self; } +}; class CResult_InitDecodeErrorZ { private: LDKCResult_InitDecodeErrorZ self; @@ -2936,6 +2951,21 @@ public: const LDKCVec_u64Z* operator &() const { return &self; } const LDKCVec_u64Z* operator ->() const { return &self; } }; +class CResult_StringErrorZ { +private: + LDKCResult_StringErrorZ self; +public: + CResult_StringErrorZ(const CResult_StringErrorZ&) = delete; + CResult_StringErrorZ(CResult_StringErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CResult_StringErrorZ)); } + CResult_StringErrorZ(LDKCResult_StringErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCResult_StringErrorZ)); } + operator LDKCResult_StringErrorZ() && { LDKCResult_StringErrorZ res = self; memset(&self, 0, sizeof(LDKCResult_StringErrorZ)); return res; } + ~CResult_StringErrorZ() { CResult_StringErrorZ_free(self); } + CResult_StringErrorZ& operator=(CResult_StringErrorZ&& o) { CResult_StringErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CResult_StringErrorZ)); return *this; } + LDKCResult_StringErrorZ* operator &() { return &self; } + LDKCResult_StringErrorZ* operator ->() { return &self; } + const LDKCResult_StringErrorZ* operator &() const { return &self; } + const LDKCResult_StringErrorZ* operator ->() const { return &self; } +}; class CResult_NoneErrorZ { private: LDKCResult_NoneErrorZ self; @@ -2966,21 +2996,6 @@ public: const LDKC2Tuple_TxidCVec_C2Tuple_u32ScriptZZZ* operator &() const { return &self; } const LDKC2Tuple_TxidCVec_C2Tuple_u32ScriptZZZ* operator ->() const { return &self; } }; -class CVec_RouteHintZ { -private: - LDKCVec_RouteHintZ self; -public: - CVec_RouteHintZ(const CVec_RouteHintZ&) = delete; - CVec_RouteHintZ(CVec_RouteHintZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_RouteHintZ)); } - CVec_RouteHintZ(LDKCVec_RouteHintZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_RouteHintZ)); } - operator LDKCVec_RouteHintZ() && { LDKCVec_RouteHintZ res = self; memset(&self, 0, sizeof(LDKCVec_RouteHintZ)); return res; } - ~CVec_RouteHintZ() { CVec_RouteHintZ_free(self); } - CVec_RouteHintZ& operator=(CVec_RouteHintZ&& o) { CVec_RouteHintZ_free(self); self = o.self; memset(&o, 0, sizeof(CVec_RouteHintZ)); return *this; } - LDKCVec_RouteHintZ* operator &() { return &self; } - LDKCVec_RouteHintZ* operator ->() { return &self; } - const LDKCVec_RouteHintZ* operator &() const { return &self; } - const LDKCVec_RouteHintZ* operator ->() const { return &self; } -}; class CVec_CVec_RouteHopZZ { private: LDKCVec_CVec_RouteHopZZ self; diff --git a/lightning-c-bindings/include/rust_types.h b/lightning-c-bindings/include/rust_types.h index e5070f5..12dbd36 100644 --- a/lightning-c-bindings/include/rust_types.h +++ b/lightning-c-bindings/include/rust_types.h @@ -52,8 +52,8 @@ struct nativeRouteHopOpaque; typedef struct nativeRouteHopOpaque LDKnativeRouteHop; struct nativeRouteOpaque; typedef struct nativeRouteOpaque LDKnativeRoute; -struct nativeRouteHintOpaque; -typedef struct nativeRouteHintOpaque LDKnativeRouteHint; +struct nativeRouteHintHopOpaque; +typedef struct nativeRouteHintHopOpaque LDKnativeRouteHintHop; struct nativeIgnoringMessageHandlerOpaque; typedef struct nativeIgnoringMessageHandlerOpaque LDKnativeIgnoringMessageHandler; struct nativeErroringMessageHandlerOpaque; diff --git a/lightning-c-bindings/src/c_types/derived.rs b/lightning-c-bindings/src/c_types/derived.rs index 7d66394..f875efb 100644 --- a/lightning-c-bindings/src/c_types/derived.rs +++ b/lightning-c-bindings/src/c_types/derived.rs @@ -1368,6 +1368,80 @@ impl Clone for CResult_CVec_SignatureZNoneZ { /// but with all dynamically-allocated buffers duplicated in new buffers. pub extern "C" fn CResult_CVec_SignatureZNoneZ_clone(orig: &CResult_CVec_SignatureZNoneZ) -> CResult_CVec_SignatureZNoneZ { orig.clone() } #[repr(C)] +/// The contents of CResult_StringErrorZ +pub union CResult_StringErrorZPtr { + /// 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::c_types::derived::CVec_u8Z, + /// A pointer to the contents in the error state. + /// Reading from this pointer when `result_ok` is set is undefined. + pub err: *mut crate::c_types::Secp256k1Error, +} +#[repr(C)] +/// A CResult_StringErrorZ represents the result of a fallible operation, +/// containing a crate::c_types::derived::CVec_u8Z on success and a crate::c_types::Secp256k1Error on failure. +/// `result_ok` indicates the overall state, and the contents are provided via `contents`. +pub struct CResult_StringErrorZ { + /// The contents of this CResult_StringErrorZ, accessible via either + /// `err` or `result` depending on the state of `result_ok`. + pub contents: CResult_StringErrorZPtr, + /// Whether this CResult_StringErrorZ represents a success state. + pub result_ok: bool, +} +#[no_mangle] +/// Creates a new CResult_StringErrorZ in the success state. +pub extern "C" fn CResult_StringErrorZ_ok(o: crate::c_types::derived::CVec_u8Z) -> CResult_StringErrorZ { + CResult_StringErrorZ { + contents: CResult_StringErrorZPtr { + result: Box::into_raw(Box::new(o)), + }, + result_ok: true, + } +} +#[no_mangle] +/// Creates a new CResult_StringErrorZ in the error state. +pub extern "C" fn CResult_StringErrorZ_err(e: crate::c_types::Secp256k1Error) -> CResult_StringErrorZ { + CResult_StringErrorZ { + contents: CResult_StringErrorZPtr { + err: Box::into_raw(Box::new(e)), + }, + result_ok: false, + } +} +#[no_mangle] +/// Frees any resources used by the CResult_StringErrorZ. +pub extern "C" fn CResult_StringErrorZ_free(_res: CResult_StringErrorZ) { } +impl Drop for CResult_StringErrorZ { + 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_StringErrorZ { + 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_StringErrorZPtr { result } + } else { + let err = unsafe { o.contents.err }; + unsafe { o.contents.err = std::ptr::null_mut(); } + CResult_StringErrorZPtr { err } + }; + Self { + contents, + result_ok: o.result_ok, + } + } +} +#[repr(C)] /// The contents of CResult_ChannelMonitorUpdateDecodeErrorZ pub union CResult_ChannelMonitorUpdateDecodeErrorZPtr { /// A pointer to the contents in the success state. @@ -2649,29 +2723,29 @@ impl Clone for CVec_ChannelDetailsZ { } } #[repr(C)] -/// A dynamically-allocated array of crate::lightning::routing::router::RouteHints of arbitrary size. +/// A dynamically-allocated array of crate::lightning::routing::router::RouteHintHops of arbitrary size. /// This corresponds to std::vector in C++ -pub struct CVec_RouteHintZ { +pub struct CVec_RouteHintHopZ { /// The elements in the array. /// If datalen is non-0 this must be a valid, non-NULL pointer allocated by malloc(). - pub data: *mut crate::lightning::routing::router::RouteHint, + pub data: *mut crate::lightning::routing::router::RouteHintHop, /// The number of elements pointed to by `data`. pub datalen: usize } -impl CVec_RouteHintZ { - #[allow(unused)] pub(crate) fn into_rust(&mut self) -> Vec { +impl CVec_RouteHintHopZ { + #[allow(unused)] pub(crate) fn into_rust(&mut self) -> Vec { if self.datalen == 0 { return Vec::new(); } let ret = unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }.into(); self.data = std::ptr::null_mut(); self.datalen = 0; ret } - #[allow(unused)] pub(crate) fn as_slice(&self) -> &[crate::lightning::routing::router::RouteHint] { + #[allow(unused)] pub(crate) fn as_slice(&self) -> &[crate::lightning::routing::router::RouteHintHop] { unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) } } } -impl From> for CVec_RouteHintZ { - fn from(v: Vec) -> Self { +impl From> for CVec_RouteHintHopZ { + fn from(v: Vec) -> Self { let datalen = v.len(); let data = Box::into_raw(v.into_boxed_slice()); Self { datalen, data: unsafe { (*data).as_mut_ptr() } } @@ -2679,14 +2753,14 @@ impl From> for CVec_RouteHintZ } #[no_mangle] /// Frees the buffer pointed to by `data` if `datalen` is non-0. -pub extern "C" fn CVec_RouteHintZ_free(_res: CVec_RouteHintZ) { } -impl Drop for CVec_RouteHintZ { +pub extern "C" fn CVec_RouteHintHopZ_free(_res: CVec_RouteHintHopZ) { } +impl Drop for CVec_RouteHintHopZ { fn drop(&mut self) { if self.datalen == 0 { return; } unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }; } } -impl Clone for CVec_RouteHintZ { +impl Clone for CVec_RouteHintHopZ { fn clone(&self) -> Self { let mut res = Vec::new(); if self.datalen == 0 { return Self::from(res); } diff --git a/lightning-c-bindings/src/lightning/routing/router.rs b/lightning-c-bindings/src/lightning/routing/router.rs index 211b44f..81b9bef 100644 --- a/lightning-c-bindings/src/lightning/routing/router.rs +++ b/lightning-c-bindings/src/lightning/routing/router.rs @@ -270,18 +270,18 @@ pub extern "C" fn Route_read(ser: crate::c_types::u8slice) -> crate::c_types::de local_res } -use lightning::routing::router::RouteHint as nativeRouteHintImport; -type nativeRouteHint = nativeRouteHintImport; +use lightning::routing::router::RouteHintHop as nativeRouteHintHopImport; +type nativeRouteHintHop = nativeRouteHintHopImport; /// A channel descriptor which provides a last-hop route to get_route #[must_use] #[repr(C)] -pub struct RouteHint { +pub struct RouteHintHop { /// 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 nativeRouteHint, + pub inner: *mut nativeRouteHintHop, /// 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 @@ -289,25 +289,25 @@ pub struct RouteHint { pub is_owned: bool, } -impl Drop for RouteHint { +impl Drop for RouteHintHop { fn drop(&mut self) { - if self.is_owned && !<*mut nativeRouteHint>::is_null(self.inner) { + if self.is_owned && !<*mut nativeRouteHintHop>::is_null(self.inner) { let _ = unsafe { Box::from_raw(self.inner) }; } } } -/// Frees any resources used by the RouteHint, if is_owned is set and inner is non-NULL. +/// Frees any resources used by the RouteHintHop, if is_owned is set and inner is non-NULL. #[no_mangle] -pub extern "C" fn RouteHint_free(this_obj: RouteHint) { } +pub extern "C" fn RouteHintHop_free(this_obj: RouteHintHop) { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn RouteHint_free_void(this_ptr: *mut c_void) { - unsafe { let _ = Box::from_raw(this_ptr as *mut nativeRouteHint); } +extern "C" fn RouteHintHop_free_void(this_ptr: *mut c_void) { + unsafe { let _ = Box::from_raw(this_ptr as *mut nativeRouteHintHop); } } #[allow(unused)] /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy -impl RouteHint { - pub(crate) fn take_inner(mut self) -> *mut nativeRouteHint { +impl RouteHintHop { + pub(crate) fn take_inner(mut self) -> *mut nativeRouteHintHop { assert!(self.is_owned); let ret = self.inner; self.inner = std::ptr::null_mut(); @@ -316,81 +316,81 @@ impl RouteHint { } /// The node_id of the non-target end of the route #[no_mangle] -pub extern "C" fn RouteHint_get_src_node_id(this_ptr: &RouteHint) -> crate::c_types::PublicKey { +pub extern "C" fn RouteHintHop_get_src_node_id(this_ptr: &RouteHintHop) -> crate::c_types::PublicKey { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.src_node_id; crate::c_types::PublicKey::from_rust(&(*inner_val)) } /// The node_id of the non-target end of the route #[no_mangle] -pub extern "C" fn RouteHint_set_src_node_id(this_ptr: &mut RouteHint, mut val: crate::c_types::PublicKey) { +pub extern "C" fn RouteHintHop_set_src_node_id(this_ptr: &mut RouteHintHop, mut val: crate::c_types::PublicKey) { unsafe { &mut *this_ptr.inner }.src_node_id = val.into_rust(); } /// The short_channel_id of this channel #[no_mangle] -pub extern "C" fn RouteHint_get_short_channel_id(this_ptr: &RouteHint) -> u64 { +pub extern "C" fn RouteHintHop_get_short_channel_id(this_ptr: &RouteHintHop) -> u64 { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.short_channel_id; (*inner_val) } /// The short_channel_id of this channel #[no_mangle] -pub extern "C" fn RouteHint_set_short_channel_id(this_ptr: &mut RouteHint, mut val: u64) { +pub extern "C" fn RouteHintHop_set_short_channel_id(this_ptr: &mut RouteHintHop, mut val: u64) { unsafe { &mut *this_ptr.inner }.short_channel_id = val; } /// The fees which must be paid to use this channel #[no_mangle] -pub extern "C" fn RouteHint_get_fees(this_ptr: &RouteHint) -> crate::lightning::routing::network_graph::RoutingFees { +pub extern "C" fn RouteHintHop_get_fees(this_ptr: &RouteHintHop) -> crate::lightning::routing::network_graph::RoutingFees { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.fees; crate::lightning::routing::network_graph::RoutingFees { inner: unsafe { ( (&((*inner_val)) as *const _) as *mut _) }, is_owned: false } } /// The fees which must be paid to use this channel #[no_mangle] -pub extern "C" fn RouteHint_set_fees(this_ptr: &mut RouteHint, mut val: crate::lightning::routing::network_graph::RoutingFees) { +pub extern "C" fn RouteHintHop_set_fees(this_ptr: &mut RouteHintHop, mut val: crate::lightning::routing::network_graph::RoutingFees) { unsafe { &mut *this_ptr.inner }.fees = *unsafe { Box::from_raw(val.take_inner()) }; } /// The difference in CLTV values between this node and the next node. #[no_mangle] -pub extern "C" fn RouteHint_get_cltv_expiry_delta(this_ptr: &RouteHint) -> u16 { +pub extern "C" fn RouteHintHop_get_cltv_expiry_delta(this_ptr: &RouteHintHop) -> u16 { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.cltv_expiry_delta; (*inner_val) } /// The difference in CLTV values between this node and the next node. #[no_mangle] -pub extern "C" fn RouteHint_set_cltv_expiry_delta(this_ptr: &mut RouteHint, mut val: u16) { +pub extern "C" fn RouteHintHop_set_cltv_expiry_delta(this_ptr: &mut RouteHintHop, mut val: u16) { unsafe { &mut *this_ptr.inner }.cltv_expiry_delta = val; } /// The minimum value, in msat, which must be relayed to the next hop. #[no_mangle] -pub extern "C" fn RouteHint_get_htlc_minimum_msat(this_ptr: &RouteHint) -> crate::c_types::derived::COption_u64Z { +pub extern "C" fn RouteHintHop_get_htlc_minimum_msat(this_ptr: &RouteHintHop) -> crate::c_types::derived::COption_u64Z { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.htlc_minimum_msat; let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_u64Z::None } else { { crate::c_types::derived::COption_u64Z::Some(inner_val.unwrap()) } }; local_inner_val } /// The minimum value, in msat, which must be relayed to the next hop. #[no_mangle] -pub extern "C" fn RouteHint_set_htlc_minimum_msat(this_ptr: &mut RouteHint, mut val: crate::c_types::derived::COption_u64Z) { +pub extern "C" fn RouteHintHop_set_htlc_minimum_msat(this_ptr: &mut RouteHintHop, mut val: crate::c_types::derived::COption_u64Z) { let mut local_val = if val.is_some() { Some( { val.take() }) } else { None }; unsafe { &mut *this_ptr.inner }.htlc_minimum_msat = local_val; } /// The maximum value in msat available for routing with a single HTLC. #[no_mangle] -pub extern "C" fn RouteHint_get_htlc_maximum_msat(this_ptr: &RouteHint) -> crate::c_types::derived::COption_u64Z { +pub extern "C" fn RouteHintHop_get_htlc_maximum_msat(this_ptr: &RouteHintHop) -> crate::c_types::derived::COption_u64Z { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.htlc_maximum_msat; let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_u64Z::None } else { { crate::c_types::derived::COption_u64Z::Some(inner_val.unwrap()) } }; local_inner_val } /// The maximum value in msat available for routing with a single HTLC. #[no_mangle] -pub extern "C" fn RouteHint_set_htlc_maximum_msat(this_ptr: &mut RouteHint, mut val: crate::c_types::derived::COption_u64Z) { +pub extern "C" fn RouteHintHop_set_htlc_maximum_msat(this_ptr: &mut RouteHintHop, mut val: crate::c_types::derived::COption_u64Z) { let mut local_val = if val.is_some() { Some( { val.take() }) } else { None }; unsafe { &mut *this_ptr.inner }.htlc_maximum_msat = local_val; } -/// Constructs a new RouteHint given each field +/// Constructs a new RouteHintHop given each field #[must_use] #[no_mangle] -pub extern "C" fn RouteHint_new(mut src_node_id_arg: crate::c_types::PublicKey, mut short_channel_id_arg: u64, mut fees_arg: crate::lightning::routing::network_graph::RoutingFees, mut cltv_expiry_delta_arg: u16, mut htlc_minimum_msat_arg: crate::c_types::derived::COption_u64Z, mut htlc_maximum_msat_arg: crate::c_types::derived::COption_u64Z) -> RouteHint { +pub extern "C" fn RouteHintHop_new(mut src_node_id_arg: crate::c_types::PublicKey, mut short_channel_id_arg: u64, mut fees_arg: crate::lightning::routing::network_graph::RoutingFees, mut cltv_expiry_delta_arg: u16, mut htlc_minimum_msat_arg: crate::c_types::derived::COption_u64Z, mut htlc_maximum_msat_arg: crate::c_types::derived::COption_u64Z) -> RouteHintHop { let mut local_htlc_minimum_msat_arg = if htlc_minimum_msat_arg.is_some() { Some( { htlc_minimum_msat_arg.take() }) } else { None }; let mut local_htlc_maximum_msat_arg = if htlc_maximum_msat_arg.is_some() { Some( { htlc_maximum_msat_arg.take() }) } else { None }; - RouteHint { inner: Box::into_raw(Box::new(nativeRouteHint { + RouteHintHop { inner: Box::into_raw(Box::new(nativeRouteHintHop { src_node_id: src_node_id_arg.into_rust(), short_channel_id: short_channel_id_arg, fees: *unsafe { Box::from_raw(fees_arg.take_inner()) }, @@ -399,10 +399,10 @@ pub extern "C" fn RouteHint_new(mut src_node_id_arg: crate::c_types::PublicKey, htlc_maximum_msat: local_htlc_maximum_msat_arg, })), is_owned: true } } -impl Clone for RouteHint { +impl Clone for RouteHintHop { fn clone(&self) -> Self { Self { - inner: if <*mut nativeRouteHint>::is_null(self.inner) { std::ptr::null_mut() } else { + inner: if <*mut nativeRouteHintHop>::is_null(self.inner) { std::ptr::null_mut() } else { Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) }, is_owned: true, } @@ -410,12 +410,12 @@ impl Clone for RouteHint { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method -pub(crate) extern "C" fn RouteHint_clone_void(this_ptr: *const c_void) -> *mut c_void { - Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRouteHint)).clone() })) as *mut c_void +pub(crate) extern "C" fn RouteHintHop_clone_void(this_ptr: *const c_void) -> *mut c_void { + Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRouteHintHop)).clone() })) as *mut c_void } #[no_mangle] -/// Creates a copy of the RouteHint -pub extern "C" fn RouteHint_clone(orig: &RouteHint) -> RouteHint { +/// Creates a copy of the RouteHintHop +pub extern "C" fn RouteHintHop_clone(orig: &RouteHintHop) -> RouteHintHop { orig.clone() } /// Gets a route from us (payer) to the given target node (payee). @@ -438,7 +438,7 @@ pub extern "C" fn RouteHint_clone(orig: &RouteHint) -> RouteHint { /// equal), however the enabled/disabled bit on such channels as well as the /// htlc_minimum_msat/htlc_maximum_msat *are* checked as they may change based on the receiving node. #[no_mangle] -pub extern "C" fn get_route(mut our_node_id: crate::c_types::PublicKey, network: &crate::lightning::routing::network_graph::NetworkGraph, mut payee: crate::c_types::PublicKey, mut payee_features: crate::lightning::ln::features::InvoiceFeatures, first_hops: *mut crate::c_types::derived::CVec_ChannelDetailsZ, mut last_hops: crate::c_types::derived::CVec_RouteHintZ, mut final_value_msat: u64, mut final_cltv: u32, mut logger: crate::lightning::util::logger::Logger) -> crate::c_types::derived::CResult_RouteLightningErrorZ { +pub extern "C" fn get_route(mut our_node_id: crate::c_types::PublicKey, network: &crate::lightning::routing::network_graph::NetworkGraph, mut payee: crate::c_types::PublicKey, mut payee_features: crate::lightning::ln::features::InvoiceFeatures, first_hops: *mut crate::c_types::derived::CVec_ChannelDetailsZ, mut last_hops: crate::c_types::derived::CVec_RouteHintHopZ, mut final_value_msat: u64, mut final_cltv: u32, mut logger: crate::lightning::util::logger::Logger) -> crate::c_types::derived::CResult_RouteLightningErrorZ { let mut local_payee_features = if payee_features.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(payee_features.take_inner()) } }) }; let mut local_first_hops_base = if first_hops == std::ptr::null_mut() { None } else { Some( { let mut local_first_hops_0 = Vec::new(); for mut item in unsafe { &mut *first_hops }.as_slice().iter() { local_first_hops_0.push( { unsafe { &*item.inner } }); }; local_first_hops_0 }) }; let mut local_first_hops = local_first_hops_base.as_ref().map(|a| &a[..]); let mut local_last_hops = Vec::new(); for mut item in last_hops.as_slice().iter() { local_last_hops.push( { unsafe { &*item.inner } }); }; diff --git a/lightning-c-bindings/src/lightning/util/message_signing.rs b/lightning-c-bindings/src/lightning/util/message_signing.rs new file mode 100644 index 0000000..ca1d0b9 --- /dev/null +++ b/lightning-c-bindings/src/lightning/util/message_signing.rs @@ -0,0 +1,54 @@ +// This file is Copyright its original authors, visible in version control +// history and in the source files from which this was generated. +// +// This file is licensed under the license available in the LICENSE or LICENSE.md +// file in the root of this repository or, if no such file exists, the same +// license as that which applies to the original source files from which this +// source was automatically generated. + +//! Lightning message signing and verification lives here. These tools can be used to sign messages using the node's +//! secret so receivers are sure that they come from you. You can also use this to verify that a given message comes +//! from a specific node. +//! Furthermore, these tools can be used to sign / verify messages using ephemeral keys not tied to node's identities. +//! +//! Note this is not part of the specs, but follows lnd's signing and verifying protocol, which can is defined as follows: +//! +//! signature = zbase32(SigRec(sha256d((\"Lightning Signed Message:\" + msg))) +//! zbase32 from https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt +//! SigRec has first byte 31 + recovery id, followed by 64 byte sig. +//! +//! This implementation is compatible with both lnd's and c-lightning's +//! +//! https://lightning.readthedocs.io/lightning-signmessage.7.html +//! https://api.lightning.community/#signmessage + +use std::ffi::c_void; +use bitcoin::hashes::Hash; +use crate::c_types::*; + +/// Creates a digital signature of a message given a SecretKey, like the node's secret. +/// A receiver knowing the PublicKey (e.g. the node's id) and the message can be sure that the signature was generated by the caller. +/// Signatures are EC recoverable, meaning that given the message and the signature the PublicKey of the signer can be extracted. +#[no_mangle] +pub extern "C" fn sign(mut msg: crate::c_types::u8slice, mut sk: crate::c_types::SecretKey) -> crate::c_types::derived::CResult_StringErrorZ { + let mut ret = lightning::util::message_signing::sign(msg.to_slice(), sk.into_rust()); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { o.into_bytes().into() }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::c_types::Secp256k1Error::from_rust(e) }).into() }; + local_ret +} + +/// Recovers the PublicKey of the signer of the message given the message and the signature. +#[no_mangle] +pub extern "C" fn recover_pk(mut msg: crate::c_types::u8slice, mut sig: crate::c_types::Str) -> crate::c_types::derived::CResult_PublicKeyErrorZ { + let mut ret = lightning::util::message_signing::recover_pk(msg.to_slice(), sig.into()); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::PublicKey::from_rust(&o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::c_types::Secp256k1Error::from_rust(e) }).into() }; + local_ret +} + +/// Verifies a message was signed by a PrivateKey that derives to a given PublicKey, given a message, a signature, +/// and the PublicKey. +#[no_mangle] +pub extern "C" fn verify(mut msg: crate::c_types::u8slice, mut sig: crate::c_types::Str, mut pk: crate::c_types::PublicKey) -> bool { + let mut ret = lightning::util::message_signing::verify(msg.to_slice(), sig.into(), pk.into_rust()); + ret +} + diff --git a/lightning-c-bindings/src/lightning/util/mod.rs b/lightning-c-bindings/src/lightning/util/mod.rs index 49003dc..56b9c75 100644 --- a/lightning-c-bindings/src/lightning/util/mod.rs +++ b/lightning-c-bindings/src/lightning/util/mod.rs @@ -15,5 +15,6 @@ use crate::c_types::*; pub mod events; pub mod errors; pub mod ser; +pub mod message_signing; pub mod logger; pub mod config;