mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 07:17:40 +01:00
Merge pull request #618 from TheBlueMatt/2020-05-sample-c-bindings
C/C++ Bindings
This commit is contained in:
commit
253af8dd61
50 changed files with 26438 additions and 9 deletions
53
.github/workflows/build.yml
vendored
53
.github/workflows/build.yml
vendored
|
@ -17,11 +17,16 @@ jobs:
|
|||
include:
|
||||
- toolchain: stable
|
||||
build-net-tokio: true
|
||||
build-bindings: true
|
||||
- toolchain: beta
|
||||
build-net-tokio: true
|
||||
build-bindings: true
|
||||
- toolchain: 1.39.0
|
||||
build-net-tokio: true
|
||||
build-bindings: true
|
||||
coverage: true
|
||||
- toolchain: 1.34.2
|
||||
build-bindings: true
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
|
@ -38,6 +43,9 @@ jobs:
|
|||
- name: Build on Rust ${{ matrix.toolchain }}
|
||||
if: "! matrix.build-net-tokio"
|
||||
run: RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always -p lightning
|
||||
- name: Build bindings on Rust ${{ matrix.toolchain }}
|
||||
if: matrix.build-bindings
|
||||
run: RUSTFLAGS="-C link-dead-code" cargo build --verbose --color always -p lightning-c-bindings
|
||||
- name: Test on Rust ${{ matrix.toolchain }} with net-tokio
|
||||
if: matrix.build-net-tokio
|
||||
run: RUSTFLAGS="-C link-dead-code" cargo test --verbose --color always
|
||||
|
@ -98,3 +106,48 @@ jobs:
|
|||
run: cd fuzz && cargo test --verbose --color always
|
||||
- name: Run fuzzers
|
||||
run: cd fuzz && ./ci-fuzz.sh
|
||||
|
||||
check_bindings:
|
||||
runs-on: ubuntu-latest
|
||||
# Ubuntu's version of rustc uses its own LLVM instead of being a real native package.
|
||||
# This leaves us with an incompatible LLVM version when linking. Instead, use a real OS.
|
||||
# We further (temporarily) use Debian experimental since testing links rustc against the
|
||||
# brand-new llvm-10, but clang/llvm still default to LLVM 9.
|
||||
container: debian:experimental
|
||||
env:
|
||||
TOOLCHAIN: stable
|
||||
steps:
|
||||
- name: Install native Rust toolchain, Valgrind, and build utilitis
|
||||
run: |
|
||||
echo 'Package: llvm llvm-runtime clang lld' > /etc/apt/preferences.d/99-llvm10
|
||||
echo 'Pin: release n=experimental' >> /etc/apt/preferences.d/99-llvm10
|
||||
echo 'Pin-Priority: 995' >> /etc/apt/preferences.d/99-llvm10
|
||||
apt-get update
|
||||
apt-get -y dist-upgrade
|
||||
apt-get -y install cargo valgrind lld git g++ clang
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
- name: Install cbindgen
|
||||
run: cargo install --force cbindgen
|
||||
- name: Rebuild bindings, and check the sample app builds + links
|
||||
run: ./genbindings.sh
|
||||
- name: Check that the latest bindings are in git
|
||||
run: |
|
||||
if [ "$(git diff)" != "" ]; then
|
||||
# cbindgen's bindings output order can be FS-dependant, so check that the lines are all the same:
|
||||
mv lightning-c-bindings/include/lightning.h lightning-c-bindings/include/lightning.h.new
|
||||
git checkout lightning-c-bindings/include/lightning.h
|
||||
cat lightning-c-bindings/include/lightning.h | sort > lightning-c-bindings/include/lightning.h.sorted
|
||||
cat lightning-c-bindings/include/lightning.h.new | sort > lightning-c-bindings/include/lightning.h.new.sorted
|
||||
diff lightning-c-bindings/include/lightning.h.sorted lightning-c-bindings/include/lightning.h.new.sorted
|
||||
#
|
||||
mv lightning-c-bindings/include/lightningpp.hpp lightning-c-bindings/include/lightningpp.hpp.new
|
||||
git checkout lightning-c-bindings/include/lightningpp.hpp
|
||||
cat lightning-c-bindings/include/lightningpp.hpp | sort > lightning-c-bindings/include/lightningpp.hpp.sorted
|
||||
cat lightning-c-bindings/include/lightningpp.hpp.new | sort > lightning-c-bindings/include/lightningpp.hpp.new.sorted
|
||||
diff lightning-c-bindings/include/lightningpp.hpp.sorted lightning-c-bindings/include/lightningpp.hpp.new.sorted
|
||||
#
|
||||
[ "$(diff lightning-c-bindings/include/lightning.h.sorted lightning-c-bindings/include/lightning.h.new.sorted)" != "" ] && exit 2
|
||||
[ "$(diff lightning-c-bindings/include/lightningpp.hpp.sorted lightning-c-bindings/include/lightningpp.hpp.new.sorted)" != "" ] && exit 3
|
||||
git diff --exit-code
|
||||
fi
|
||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -3,8 +3,17 @@
|
|||
members = [
|
||||
"lightning",
|
||||
"lightning-net-tokio",
|
||||
"lightning-c-bindings",
|
||||
]
|
||||
|
||||
# Our tests do actual crypo and lots of work, the tradeoff for -O1 is well worth it
|
||||
[profile.dev]
|
||||
[profile.test]
|
||||
opt-level = 1
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
lto = true
|
||||
panic = "abort"
|
||||
|
|
12
c-bindings-gen/Cargo.toml
Normal file
12
c-bindings-gen/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "c-bindings-gen"
|
||||
version = "0.0.1"
|
||||
authors = ["Matt Corallo"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "1", features = ["full", "extra-traits"] }
|
||||
proc-macro2 = "1"
|
||||
|
||||
# We're not in the workspace as we're just a binary code generator:
|
||||
[workspace]
|
373
c-bindings-gen/src/blocks.rs
Normal file
373
c-bindings-gen/src/blocks.rs
Normal file
|
@ -0,0 +1,373 @@
|
|||
//! Printing logic for basic blocks of Rust-mapped code - parts of functions and declarations but
|
||||
//! not the full mapping logic.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use proc_macro2::{TokenTree, Span};
|
||||
|
||||
use crate::types::*;
|
||||
|
||||
/// Writes out a C++ wrapper class for the given type, which contains various utilities to access
|
||||
/// the underlying C-mapped type safely avoiding some common memory management issues by handling
|
||||
/// resource-freeing and prevending accidental raw copies.
|
||||
pub fn write_cpp_wrapper(cpp_header_file: &mut File, ty: &str, has_destructor: bool) {
|
||||
writeln!(cpp_header_file, "class {} {{", ty).unwrap();
|
||||
writeln!(cpp_header_file, "private:").unwrap();
|
||||
writeln!(cpp_header_file, "\tLDK{} self;", ty).unwrap();
|
||||
writeln!(cpp_header_file, "public:").unwrap();
|
||||
writeln!(cpp_header_file, "\t{}(const {}&) = delete;", ty, ty).unwrap();
|
||||
if has_destructor {
|
||||
writeln!(cpp_header_file, "\t~{}() {{ {}_free(self); }}", ty, ty).unwrap();
|
||||
}
|
||||
writeln!(cpp_header_file, "\t{}({}&& o) : self(o.self) {{ memset(&o, 0, sizeof({})); }}", ty, ty, ty).unwrap();
|
||||
writeln!(cpp_header_file, "\t{}(LDK{}&& m_self) : self(m_self) {{ memset(&m_self, 0, sizeof(LDK{})); }}", ty, ty, ty).unwrap();
|
||||
writeln!(cpp_header_file, "\toperator LDK{}() {{ LDK{} res = self; memset(&self, 0, sizeof(LDK{})); return res; }}", ty, ty, ty).unwrap();
|
||||
writeln!(cpp_header_file, "\tLDK{}* operator &() {{ return &self; }}", ty).unwrap();
|
||||
writeln!(cpp_header_file, "\tLDK{}* operator ->() {{ return &self; }}", ty).unwrap();
|
||||
writeln!(cpp_header_file, "\tconst LDK{}* operator &() const {{ return &self; }}", ty).unwrap();
|
||||
writeln!(cpp_header_file, "\tconst LDK{}* operator ->() const {{ return &self; }}", ty).unwrap();
|
||||
writeln!(cpp_header_file, "}};").unwrap();
|
||||
}
|
||||
|
||||
/// Prints the docs from a given attribute list unless its tagged no export
|
||||
pub fn writeln_docs<W: std::io::Write>(w: &mut W, attrs: &[syn::Attribute], prefix: &str) {
|
||||
for attr in attrs.iter() {
|
||||
let tokens_clone = attr.tokens.clone();
|
||||
let mut token_iter = tokens_clone.into_iter();
|
||||
if let Some(token) = token_iter.next() {
|
||||
match token {
|
||||
TokenTree::Punct(c) if c.as_char() == '=' => {
|
||||
// syn gets '=' from '///' or '//!' as it is syntax for #[doc = ""]
|
||||
},
|
||||
TokenTree::Group(_) => continue, // eg #[derive()]
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
} else { continue; }
|
||||
match attr.style {
|
||||
syn::AttrStyle::Inner(_) => {
|
||||
match token_iter.next().unwrap() {
|
||||
TokenTree::Literal(lit) => {
|
||||
// Drop the first and last chars from lit as they are always "
|
||||
let doc = format!("{}", lit);
|
||||
writeln!(w, "{}//!{}", prefix, &doc[1..doc.len() - 1]).unwrap();
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
},
|
||||
syn::AttrStyle::Outer => {
|
||||
match token_iter.next().unwrap() {
|
||||
TokenTree::Literal(lit) => {
|
||||
// Drop the first and last chars from lit as they are always "
|
||||
let doc = format!("{}", lit);
|
||||
writeln!(w, "{}///{}", prefix, &doc[1..doc.len() - 1]).unwrap();
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Print the parameters in a method declaration, starting after the open parenthesis, through and
|
||||
/// including the closing parenthesis and return value, but not including the open bracket or any
|
||||
/// trailing semicolons.
|
||||
///
|
||||
/// Usable both for a function definition and declaration.
|
||||
///
|
||||
/// this_param is used when returning Self or accepting a self parameter, and should be the
|
||||
/// concrete, mapped type.
|
||||
pub fn write_method_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, associated_types: &HashMap<&syn::Ident, &syn::Ident>, this_param: &str, types: &mut TypeResolver, generics: Option<&GenericTypes>, self_ptr: bool, fn_decl: bool) {
|
||||
if sig.constness.is_some() || sig.asyncness.is_some() || sig.unsafety.is_some() ||
|
||||
sig.abi.is_some() || sig.variadic.is_some() {
|
||||
unimplemented!();
|
||||
}
|
||||
if sig.generics.lt_token.is_some() {
|
||||
for generic in sig.generics.params.iter() {
|
||||
match generic {
|
||||
syn::GenericParam::Type(_)|syn::GenericParam::Lifetime(_) => {
|
||||
// We ignore these, if they're not on skipped args, we'll blow up
|
||||
// later, and lifetimes we just hope the C client enforces.
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut first_arg = true;
|
||||
let mut num_unused = 0;
|
||||
for inp in sig.inputs.iter() {
|
||||
match inp {
|
||||
syn::FnArg::Receiver(recv) => {
|
||||
if !recv.attrs.is_empty() || recv.reference.is_none() { unimplemented!(); }
|
||||
write!(w, "this_arg: {}{}",
|
||||
match (self_ptr, recv.mutability.is_some()) {
|
||||
(true, true) => "*mut ",
|
||||
(true, false) => "*const ",
|
||||
(false, true) => "&mut ",
|
||||
(false, false) => "&",
|
||||
}, this_param).unwrap();
|
||||
assert!(first_arg);
|
||||
first_arg = false;
|
||||
},
|
||||
syn::FnArg::Typed(arg) => {
|
||||
if types.skip_arg(&*arg.ty, generics) { continue; }
|
||||
if !arg.attrs.is_empty() { unimplemented!(); }
|
||||
let mut is_ref = if let syn::Type::Reference(_) = *arg.ty { true } else { false };
|
||||
if let syn::Type::Reference(syn::TypeReference { ref elem, .. }) = *arg.ty {
|
||||
if let syn::Type::Slice(_) = &**elem {
|
||||
// Slices are mapped to non-ref Vec types, so we want them to be mut
|
||||
// letting us drain(..) the underlying Vec.
|
||||
is_ref = false;
|
||||
}
|
||||
}
|
||||
match &*arg.pat {
|
||||
syn::Pat::Ident(ident) => {
|
||||
if !ident.attrs.is_empty() || ident.subpat.is_some() {
|
||||
unimplemented!();
|
||||
}
|
||||
write!(w, "{}{}{}: ", if first_arg { "" } else { ", " }, if is_ref || !fn_decl { "" } else { "mut " }, ident.ident).unwrap();
|
||||
first_arg = false;
|
||||
},
|
||||
syn::Pat::Wild(wild) => {
|
||||
if !wild.attrs.is_empty() { unimplemented!(); }
|
||||
write!(w, "{}unused_{}: ", if first_arg { "" } else { ", " }, num_unused).unwrap();
|
||||
num_unused += 1;
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
types.write_c_type(w, &*arg.ty, generics, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
write!(w, ")").unwrap();
|
||||
match &sig.output {
|
||||
syn::ReturnType::Type(_, rtype) => {
|
||||
write!(w, " -> ").unwrap();
|
||||
if let Some(mut remaining_path) = first_seg_self(&*rtype) {
|
||||
if let Some(associated_seg) = get_single_remaining_path_seg(&mut remaining_path) {
|
||||
// We're returning an associated type in a trait impl. Its probably a safe bet
|
||||
// that its also a trait, so just return the trait type.
|
||||
let real_type = associated_types.get(associated_seg).unwrap();
|
||||
types.write_c_type(w, &syn::Type::Path(syn::TypePath { qself: None,
|
||||
path: syn::PathSegment {
|
||||
ident: (*real_type).clone(),
|
||||
arguments: syn::PathArguments::None
|
||||
}.into()
|
||||
}), generics, true);
|
||||
} else {
|
||||
write!(w, "{}", this_param).unwrap();
|
||||
}
|
||||
} else {
|
||||
if let syn::Type::Reference(r) = &**rtype {
|
||||
// We can't return a reference, cause we allocate things on the stack.
|
||||
types.write_c_type(w, &*r.elem, generics, true);
|
||||
} else {
|
||||
types.write_c_type(w, &*rtype, generics, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Print the main part of a method declaration body, starting with a newline after the function
|
||||
/// open bracket and converting each function parameter to or from C-mapped types. Ends with "let
|
||||
/// mut ret = " assuming the next print will be the unmapped Rust function to call followed by the
|
||||
/// parameters we mapped to/from C here.
|
||||
pub fn write_method_var_decl_body<W: std::io::Write>(w: &mut W, sig: &syn::Signature, extra_indent: &str, types: &TypeResolver, generics: Option<&GenericTypes>, to_c: bool) {
|
||||
let mut num_unused = 0;
|
||||
for inp in sig.inputs.iter() {
|
||||
match inp {
|
||||
syn::FnArg::Receiver(_) => {},
|
||||
syn::FnArg::Typed(arg) => {
|
||||
if types.skip_arg(&*arg.ty, generics) { continue; }
|
||||
if !arg.attrs.is_empty() { unimplemented!(); }
|
||||
macro_rules! write_new_var {
|
||||
($ident: expr, $ty: expr) => {
|
||||
if to_c {
|
||||
if types.write_to_c_conversion_new_var(w, &$ident, &$ty, generics, false) {
|
||||
write!(w, "\n\t{}", extra_indent).unwrap();
|
||||
}
|
||||
} else {
|
||||
if types.write_from_c_conversion_new_var(w, &$ident, &$ty, generics) {
|
||||
write!(w, "\n\t{}", extra_indent).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match &*arg.pat {
|
||||
syn::Pat::Ident(ident) => {
|
||||
if !ident.attrs.is_empty() || ident.subpat.is_some() {
|
||||
unimplemented!();
|
||||
}
|
||||
write_new_var!(ident.ident, *arg.ty);
|
||||
},
|
||||
syn::Pat::Wild(w) => {
|
||||
if !w.attrs.is_empty() { unimplemented!(); }
|
||||
write_new_var!(syn::Ident::new(&format!("unused_{}", num_unused), Span::call_site()), *arg.ty);
|
||||
num_unused += 1;
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match &sig.output {
|
||||
syn::ReturnType::Type(_, _) => {
|
||||
write!(w, "let mut ret = ").unwrap();
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints the parameters in a method call, starting after the open parenthesis and ending with a
|
||||
/// final return statement returning the method's result. Should be followed by a single closing
|
||||
/// bracket.
|
||||
///
|
||||
/// The return value is expected to be bound to a variable named `ret` which is available after a
|
||||
/// method-call-ending semicolon.
|
||||
pub fn write_method_call_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, associated_types: &HashMap<&syn::Ident, &syn::Ident>, extra_indent: &str, types: &TypeResolver, generics: Option<&GenericTypes>, this_type: &str, to_c: bool) {
|
||||
let mut first_arg = true;
|
||||
let mut num_unused = 0;
|
||||
for inp in sig.inputs.iter() {
|
||||
match inp {
|
||||
syn::FnArg::Receiver(recv) => {
|
||||
if !recv.attrs.is_empty() || recv.reference.is_none() { unimplemented!(); }
|
||||
if to_c {
|
||||
write!(w, "self.this_arg").unwrap();
|
||||
first_arg = false;
|
||||
}
|
||||
},
|
||||
syn::FnArg::Typed(arg) => {
|
||||
if types.skip_arg(&*arg.ty, generics) {
|
||||
if !to_c {
|
||||
if !first_arg {
|
||||
write!(w, ", ").unwrap();
|
||||
}
|
||||
first_arg = false;
|
||||
types.no_arg_to_rust(w, &*arg.ty, generics);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if !arg.attrs.is_empty() { unimplemented!(); }
|
||||
macro_rules! write_ident {
|
||||
($ident: expr) => {
|
||||
if !first_arg {
|
||||
write!(w, ", ").unwrap();
|
||||
}
|
||||
first_arg = false;
|
||||
if to_c {
|
||||
types.write_to_c_conversion_inline_prefix(w, &*arg.ty, generics, false);
|
||||
write!(w, "{}", $ident).unwrap();
|
||||
types.write_to_c_conversion_inline_suffix(w, &*arg.ty, generics, false);
|
||||
} else {
|
||||
types.write_from_c_conversion_prefix(w, &*arg.ty, generics);
|
||||
write!(w, "{}", $ident).unwrap();
|
||||
types.write_from_c_conversion_suffix(w, &*arg.ty, generics);
|
||||
}
|
||||
}
|
||||
}
|
||||
match &*arg.pat {
|
||||
syn::Pat::Ident(ident) => {
|
||||
if !ident.attrs.is_empty() || ident.subpat.is_some() {
|
||||
unimplemented!();
|
||||
}
|
||||
write_ident!(ident.ident);
|
||||
},
|
||||
syn::Pat::Wild(w) => {
|
||||
if !w.attrs.is_empty() { unimplemented!(); }
|
||||
write_ident!(format!("unused_{}", num_unused));
|
||||
num_unused += 1;
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
write!(w, ")").unwrap();
|
||||
match &sig.output {
|
||||
syn::ReturnType::Type(_, rtype) => {
|
||||
write!(w, ";\n\t{}", extra_indent).unwrap();
|
||||
|
||||
if to_c && first_seg_self(&*rtype).is_some() {
|
||||
// Assume rather blindly that we're returning an associated trait from a C fn call to a Rust trait object.
|
||||
write!(w, "ret").unwrap();
|
||||
} else if !to_c && first_seg_self(&*rtype).is_some() {
|
||||
if let Some(mut remaining_path) = first_seg_self(&*rtype) {
|
||||
if let Some(associated_seg) = get_single_remaining_path_seg(&mut remaining_path) {
|
||||
let real_type = associated_types.get(associated_seg).unwrap();
|
||||
if let Some(t) = types.crate_types.traits.get(&types.maybe_resolve_ident(&real_type).unwrap()) {
|
||||
// We're returning an associated trait from a Rust fn call to a C trait
|
||||
// object.
|
||||
writeln!(w, "let mut rust_obj = {} {{ inner: Box::into_raw(Box::new(ret)), is_owned: true }};", this_type).unwrap();
|
||||
writeln!(w, "\t{}let mut ret = {}_as_{}(&rust_obj);", extra_indent, this_type, t.ident).unwrap();
|
||||
writeln!(w, "\t{}// 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", extra_indent).unwrap();
|
||||
writeln!(w, "\t{}rust_obj.inner = std::ptr::null_mut();", extra_indent).unwrap();
|
||||
writeln!(w, "\t{}ret.free = Some({}_free_void);", extra_indent, this_type).unwrap();
|
||||
writeln!(w, "\t{}ret", extra_indent).unwrap();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
write!(w, "{} {{ inner: Box::into_raw(Box::new(ret)), is_owned: true }}", this_type).unwrap();
|
||||
} else if to_c {
|
||||
let new_var = types.write_from_c_conversion_new_var(w, &syn::Ident::new("ret", Span::call_site()), rtype, generics);
|
||||
if new_var {
|
||||
write!(w, "\n\t{}", extra_indent).unwrap();
|
||||
}
|
||||
types.write_from_c_conversion_prefix(w, &*rtype, generics);
|
||||
write!(w, "ret").unwrap();
|
||||
types.write_from_c_conversion_suffix(w, &*rtype, generics);
|
||||
} else {
|
||||
let ret_returned = if let syn::Type::Reference(_) = &**rtype { true } else { false };
|
||||
let new_var = types.write_to_c_conversion_new_var(w, &syn::Ident::new("ret", Span::call_site()), &rtype, generics, true);
|
||||
if new_var {
|
||||
write!(w, "\n\t{}", extra_indent).unwrap();
|
||||
}
|
||||
types.write_to_c_conversion_inline_prefix(w, &rtype, generics, true);
|
||||
write!(w, "{}ret", if ret_returned && !new_var { "*" } else { "" }).unwrap();
|
||||
types.write_to_c_conversion_inline_suffix(w, &rtype, generics, true);
|
||||
}
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints concrete generic parameters for a struct/trait/function, including the less-than and
|
||||
/// greater-than symbols, if any generic parameters are defined.
|
||||
pub fn maybe_write_generics<W: std::io::Write>(w: &mut W, generics: &syn::Generics, types: &TypeResolver, concrete_lifetimes: bool) {
|
||||
let mut gen_types = GenericTypes::new();
|
||||
assert!(gen_types.learn_generics(generics, types));
|
||||
if !generics.params.is_empty() {
|
||||
write!(w, "<").unwrap();
|
||||
for (idx, generic) in generics.params.iter().enumerate() {
|
||||
match generic {
|
||||
syn::GenericParam::Type(type_param) => {
|
||||
let mut printed_param = false;
|
||||
for bound in type_param.bounds.iter() {
|
||||
if let syn::TypeParamBound::Trait(trait_bound) = bound {
|
||||
assert_simple_bound(&trait_bound);
|
||||
write!(w, "{}{}", if idx != 0 { ", " } else { "" }, gen_types.maybe_resolve_ident(&type_param.ident).unwrap()).unwrap();
|
||||
if printed_param {
|
||||
unimplemented!("Can't print generic params that have multiple non-lifetime bounds");
|
||||
}
|
||||
printed_param = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
syn::GenericParam::Lifetime(lt) => {
|
||||
if concrete_lifetimes {
|
||||
write!(w, "'static").unwrap();
|
||||
} else {
|
||||
write!(w, "{}'{}", if idx != 0 { ", " } else { "" }, lt.lifetime.ident).unwrap();
|
||||
}
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
write!(w, ">").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
1283
c-bindings-gen/src/main.rs
Normal file
1283
c-bindings-gen/src/main.rs
Normal file
File diff suppressed because it is too large
Load diff
2021
c-bindings-gen/src/types.rs
Normal file
2021
c-bindings-gen/src/types.rs
Normal file
File diff suppressed because it is too large
Load diff
189
genbindings.sh
Executable file
189
genbindings.sh
Executable file
|
@ -0,0 +1,189 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Generate (and reasonably test) C bindings
|
||||
|
||||
# First build the latest c-bindings-gen binary
|
||||
cd c-bindings-gen && cargo build && cd ..
|
||||
|
||||
# Then wipe all the existing C bindings (because we're being run in the right directory)
|
||||
# note that we keep the few manually-generated files first:
|
||||
mv lightning-c-bindings/src/c_types/mod.rs ./
|
||||
mv lightning-c-bindings/src/bitcoin ./
|
||||
|
||||
rm -rf lightning-c-bindings/src
|
||||
|
||||
mkdir -p lightning-c-bindings/src/c_types/
|
||||
mv ./mod.rs lightning-c-bindings/src/c_types/
|
||||
mv ./bitcoin lightning-c-bindings/src/
|
||||
|
||||
# Finally, run the c-bindings-gen binary, building fresh bindings.
|
||||
SRC="$(pwd)/lightning/src"
|
||||
OUT="$(pwd)/lightning-c-bindings/src"
|
||||
OUT_TEMPL="$(pwd)/lightning-c-bindings/src/c_types/derived.rs"
|
||||
OUT_F="$(pwd)/lightning-c-bindings/include/rust_types.h"
|
||||
OUT_CPP="$(pwd)/lightning-c-bindings/include/lightningpp.hpp"
|
||||
RUST_BACKTRACE=1 ./c-bindings-gen/target/debug/c-bindings-gen $SRC/ $OUT/ lightning $OUT_TEMPL $OUT_F $OUT_CPP
|
||||
|
||||
# Now cd to lightning-c-bindings, build the generated bindings, and call cbindgen to build a C header file
|
||||
PATH="$PATH:~/.cargo/bin"
|
||||
cd lightning-c-bindings
|
||||
cargo build
|
||||
cbindgen -v --config cbindgen.toml -o include/lightning.h >/dev/null 2>&1
|
||||
|
||||
HOST_PLATFORM="$(rustc --version --verbose | grep "host:")"
|
||||
|
||||
# cbindgen is relatively braindead when exporting typedefs -
|
||||
# it happily exports all our typedefs for private types, even with the
|
||||
# generics we specified in C mode! So we drop all those types manually here.
|
||||
if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then
|
||||
# OSX sed is for some reason not compatible with GNU sed
|
||||
sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
|
||||
else
|
||||
sed -i 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
|
||||
fi
|
||||
|
||||
# Finally, sanity-check the generated C and C++ bindings with demo apps:
|
||||
|
||||
# Naively run the C demo app:
|
||||
gcc -Wall -g -pthread demo.c ../target/debug/liblightning.a -ldl
|
||||
./a.out
|
||||
|
||||
# And run the C++ demo app in valgrind to test memory model correctness and lack of leaks.
|
||||
g++ -std=c++11 -Wall -g -pthread demo.cpp -L../target/debug/ -llightning -ldl
|
||||
if [ -x "`which valgrind`" ]; then
|
||||
LD_LIBRARY_PATH=../target/debug/ valgrind --error-exitcode=4 --memcheck:leak-check=full --show-leak-kinds=all ./a.out
|
||||
echo
|
||||
else
|
||||
echo "WARNING: Please install valgrind for more testing"
|
||||
fi
|
||||
|
||||
# Test a statically-linked C++ version, tracking the resulting binary size and runtime
|
||||
# across debug, LTO, and cross-language LTO builds (using the same compiler each time).
|
||||
clang++ -std=c++11 -Wall -pthread demo.cpp ../target/debug/liblightning.a -ldl
|
||||
./a.out >/dev/null
|
||||
echo " C++ Bin size and runtime w/o optimization:"
|
||||
ls -lha a.out
|
||||
time ./a.out > /dev/null
|
||||
|
||||
# Then, check with memory sanitizer, if we're on Linux and have rustc nightly
|
||||
if [ "$HOST_PLATFORM" = "host: x86_64-unknown-linux-gnu" ]; then
|
||||
if cargo +nightly --version >/dev/null 2>&1; then
|
||||
LLVM_V=$(rustc +nightly --version --verbose | grep "LLVM version" | awk '{ print substr($3, 0, 2); }')
|
||||
if [ -x "$(which clang-$LLVM_V)" ]; then
|
||||
cargo +nightly clean
|
||||
cargo +nightly rustc -Zbuild-std --target x86_64-unknown-linux-gnu -v -- -Zsanitizer=memory -Zsanitizer-memory-track-origins -Cforce-frame-pointers=yes
|
||||
mv ../target/x86_64-unknown-linux-gnu/debug/liblightning.* ../target/debug/
|
||||
|
||||
# Sadly, std doesn't seem to compile into something that is memsan-safe as of Aug 2020,
|
||||
# so we'll always fail, not to mention we may be linking against git rustc LLVM which
|
||||
# may differ from clang-llvm, so just allow everything here to fail.
|
||||
set +e
|
||||
|
||||
# First the C demo app...
|
||||
clang-$LLVM_V -std=c++11 -fsanitize=memory -fsanitize-memory-track-origins -Wall -g -pthread demo.c ../target/debug/liblightning.a -ldl
|
||||
./a.out
|
||||
|
||||
# ...then the C++ demo app
|
||||
clang++-$LLVM_V -std=c++11 -fsanitize=memory -fsanitize-memory-track-origins -Wall -g -pthread demo.cpp ../target/debug/liblightning.a -ldl
|
||||
./a.out >/dev/null
|
||||
|
||||
# restore exit-on-failure
|
||||
set -e
|
||||
else
|
||||
echo "WARNING: Can't use memory sanitizer without clang-$LLVM_V"
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Can't use memory sanitizer without rustc nightly"
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Can't use memory sanitizer on non-Linux, non-x86 platforms"
|
||||
fi
|
||||
|
||||
RUSTC_LLVM_V=$(rustc --version --verbose | grep "LLVM version" | awk '{ print substr($3, 0, 2); }' | tr -d '.')
|
||||
|
||||
if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then
|
||||
# Apple is special, as always, and decided that they must ensure that there is no way to identify
|
||||
# the LLVM version used. Why? Just to make your life hard.
|
||||
# This list is taken from https://en.wikipedia.org/wiki/Xcode
|
||||
APPLE_CLANG_V=$(clang --version | head -n1 | awk '{ print $4 }')
|
||||
if [ "$APPLE_CLANG_V" = "10.0.0" ]; then
|
||||
CLANG_LLVM_V="6"
|
||||
elif [ "$APPLE_CLANG_V" = "10.0.1" ]; then
|
||||
CLANG_LLVM_V="7"
|
||||
elif [ "$APPLE_CLANG_V" = "11.0.0" ]; then
|
||||
CLANG_LLVM_V="8"
|
||||
elif [ "$APPLE_CLANG_V" = "11.0.3" ]; then
|
||||
CLANG_LLVM_V="9"
|
||||
elif [ "$APPLE_CLANG_V" = "12.0.0" ]; then
|
||||
CLANG_LLVM_V="10"
|
||||
else
|
||||
echo "WARNING: Unable to identify Apple clang LLVM version"
|
||||
CLANG_LLVM_V="0"
|
||||
fi
|
||||
else
|
||||
CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 2); }' | tr -d '.')
|
||||
fi
|
||||
|
||||
if [ "$CLANG_LLVM_V" = "$RUSTC_LLVM_V" ]; then
|
||||
CLANG=clang
|
||||
CLANGPP=clang++
|
||||
elif [ "$(which clang-$RUSTC_LLVM_V)" != "" ]; then
|
||||
CLANG="$(which clang-$RUSTC_LLVM_V)"
|
||||
CLANGPP="$(which clang++-$RUSTC_LLVM_V)"
|
||||
fi
|
||||
|
||||
if [ "$CLANG" != "" -a "$CLANGPP" = "" ]; then
|
||||
echo "WARNING: It appears you have a clang-$RUSTC_LLVM_V but not clang++-$RUSTC_LLVM_V. This is common, but leaves us unable to compile C++ with LLVM $RUSTC_LLVM_V"
|
||||
echo "You should create a symlink called clang++-$RUSTC_LLVM_V pointing to $CLANG in $(dirname $CLANG)"
|
||||
fi
|
||||
|
||||
# Finally, if we're on OSX or on Linux, build the final debug binary with address sanitizer (and leave it there)
|
||||
if [ "$HOST_PLATFORM" = "host: x86_64-unknown-linux-gnu" -o "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then
|
||||
if [ "$CLANGPP" != "" ]; then
|
||||
if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then
|
||||
# OSX sed is for some reason not compatible with GNU sed
|
||||
sed -i .bk 's/,"cdylib"]/]/g' Cargo.toml
|
||||
else
|
||||
sed -i.bk 's/,"cdylib"]/]/g' Cargo.toml
|
||||
fi
|
||||
RUSTC_BOOTSTRAP=1 cargo rustc -v -- -Zsanitizer=address -Cforce-frame-pointers=yes || ( mv Cargo.toml.bk Cargo.toml; exit 1)
|
||||
mv Cargo.toml.bk Cargo.toml
|
||||
|
||||
# First the C demo app...
|
||||
$CLANG -fsanitize=address -Wall -g -pthread demo.c ../target/debug/liblightning.a -ldl
|
||||
ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' ./a.out
|
||||
|
||||
# ...then the C++ demo app
|
||||
$CLANGPP -std=c++11 -fsanitize=address -Wall -g -pthread demo.cpp ../target/debug/liblightning.a -ldl
|
||||
ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' ./a.out >/dev/null
|
||||
else
|
||||
echo "WARNING: Please install clang-$RUSTC_LLVM_V and clang++-$RUSTC_LLVM_V to build with address sanitizer"
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Can't use address sanitizer on non-Linux, non-OSX non-x86 platforms"
|
||||
fi
|
||||
|
||||
# Now build with LTO on on both C++ and rust, but without cross-language LTO:
|
||||
cargo rustc -v --release -- -C lto
|
||||
clang++ -std=c++11 -Wall -flto -O2 -pthread demo.cpp ../target/release/liblightning.a -ldl
|
||||
echo "C++ Bin size and runtime with only RL (LTO) optimized:"
|
||||
ls -lha a.out
|
||||
time ./a.out > /dev/null
|
||||
|
||||
if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then
|
||||
# Finally, test cross-language LTO. Note that this will fail if rustc and clang++
|
||||
# build against different versions of LLVM (eg when rustc is installed via rustup
|
||||
# or Ubuntu packages). This should work fine on Distros which do more involved
|
||||
# packaging than simply shipping the rustup binaries (eg Debian should Just Work
|
||||
# here).
|
||||
cargo rustc -v --release -- -C linker-plugin-lto -C lto -C link-arg=-fuse-ld=lld
|
||||
$CLANGPP -Wall -std=c++11 -flto -fuse-ld=lld -O2 -pthread demo.cpp ../target/release/liblightning.a -ldl
|
||||
echo "C++ Bin size and runtime with cross-language LTO:"
|
||||
ls -lha a.out
|
||||
time ./a.out > /dev/null
|
||||
else
|
||||
echo "WARNING: Building with cross-language LTO is not avilable on OSX or without clang-$RUSTC_LLVM_V"
|
||||
fi
|
19
lightning-c-bindings/Cargo.toml
Normal file
19
lightning-c-bindings/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "lightning-c-bindings"
|
||||
version = "0.0.1"
|
||||
authors = ["Matt Corallo"]
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
description = """
|
||||
Utilities to fetch the chain from Bitcoin Core REST/RPC Interfaces and feed them into Rust Lightning.
|
||||
"""
|
||||
|
||||
[lib]
|
||||
name = "lightning"
|
||||
crate-type = ["staticlib"
|
||||
# Note that the following line is matched exactly by genbindings to turn off dylib creation
|
||||
,"cdylib"]
|
||||
|
||||
[dependencies]
|
||||
bitcoin = "0.24"
|
||||
lightning = { version = "0.0.11", path = "../lightning" }
|
229
lightning-c-bindings/README.md
Normal file
229
lightning-c-bindings/README.md
Normal file
|
@ -0,0 +1,229 @@
|
|||
The wrapper crate and C/C++ Headers in this folder are auto-generated from the Rust-Lightning
|
||||
source by the c-bindings-gen crate contained in the source tree and
|
||||
[cbindgen](https://github.com/eqrion/cbindgen). They are intended to be used as a base for building
|
||||
language-specific bindings, and are thus incredibly low-level and may be difficult to work with
|
||||
directly.
|
||||
|
||||
In other words, if you're reading this, you're either writing bindings for a new language, or
|
||||
you're in the wrong place - individual language bindings should come with their own documentation.
|
||||
|
||||
LDK C Bindings
|
||||
==============
|
||||
|
||||
The C bindings available at include/lightning.h require inclusion of include/rust_types.h first.
|
||||
|
||||
All of the Rust-Lightning types are mapped into C equivalents which take a few forms, with the C
|
||||
type getting an `LDK` prefix to their native Rust type names.
|
||||
|
||||
#### Structs
|
||||
Structs are mapped into a simple wrapper containing a pointer to the native Rust-Lightning object
|
||||
and a flag to indicate whether the object is owned or only a reference. Such mappings usually
|
||||
generate a `X_free` function which must be called to release the allocated resources. Note that
|
||||
calling `X_free` will do nothing if the underlying pointer is NULL or if the `is_owned` flag is not
|
||||
set.
|
||||
|
||||
You MUST NOT create such wrapper structs manually, relying instead on constructors which have been
|
||||
mapped from equivalent Rust constructors.
|
||||
|
||||
Note that, thanks to the is-owned flag and the pointer being NULLable, such structs effectively
|
||||
represent `RustType`, `&RustType`, and `Option<RustType>`. Check the corresponding Rust
|
||||
documentation for the function or struct you are using to ensure you use the correct call semantics.
|
||||
The passed struct must match the call semantics or an assertion failure or NULL pointer dereference
|
||||
may occur.
|
||||
|
||||
For example, this is the mapping of ChannelManager.
|
||||
```c
|
||||
typedef struct MUST_USE_STRUCT LDKChannelManager {
|
||||
/** ... */
|
||||
LDKnativeChannelManager *inner;
|
||||
bool is_owned;
|
||||
} LDKChannelManager;
|
||||
```
|
||||
|
||||
#### Traits
|
||||
Traits are mapped into a concrete struct containing a void pointer (named `this_arg` and a jump
|
||||
table listing the functions which the trait must implement. The void pointer may be set to any value
|
||||
and is never interpreted (or dereferenced) by the bindings logic in any way. It is passed as the
|
||||
first argument to all function calls in the trait. You may wish to use it as a pointer to your own
|
||||
internal data structure, though it may also occasionally make sense to e.g. cast a file descriptor
|
||||
into a void pointer and use it to track a socket.
|
||||
|
||||
This should remind you of a C++ vtable, only written out by hand and with the class only containing
|
||||
a pointer, instead of the regular class data.
|
||||
|
||||
Each trait additionally contains `free` and `clone` function pointers, which may be NULL. The `free`
|
||||
function is passed the void pointer when the object is `Drop`ed in Rust. The `clone` function is
|
||||
passed the void pointer when the object is `Clone`ed in Rust, returning a new void pointer for the
|
||||
new object. If the `free` pointer is NULL, you will not receive any notification when the trait
|
||||
object is no longer needed. If the `clone` pointer is NULL, we assume that the trait object may be
|
||||
`memcpy()`'d to create copies. Note that if you release resources with `free` without implementing
|
||||
`clone`, you will likely end up with use-after-free bugs (as copies of the original this_arg value
|
||||
may still exist, unbeknownst to you).
|
||||
|
||||
For example, `LDKSocketDescriptor` is mapped as follows:
|
||||
```c
|
||||
typedef struct LDKSocketDescriptor {
|
||||
void *this_arg;
|
||||
/** ... */
|
||||
uintptr_t (*send_data)(void *this_arg, LDKu8slice data, bool resume_read);
|
||||
/** ... */
|
||||
void (*disconnect_socket)(void *this_arg);
|
||||
bool (*eq)(const void *this_arg, const void *other_arg);
|
||||
uint64_t (*hash)(const void *this_arg);
|
||||
void *(*clone)(const void *this_arg);
|
||||
void (*free)(void *this_arg);
|
||||
} LDKSocketDescriptor;
|
||||
```
|
||||
|
||||
##### Rust Trait Implementations
|
||||
Rust structs that implement a trait result in the generation of an `X_as_Y` function, which takes a
|
||||
C struct wrapping the Rust native object and returns a generated trait object. Such generated
|
||||
objects are only valid as long as the original Rust native object has not been `free`'d or moved as
|
||||
a part of a Rust function call (ie continues to be owned by the C struct). For example, to use an
|
||||
`LDKInMemoryChannelKeys` as a `ChannelKeys`, `InMemoryChannelKeys_as_ChannelKeys` is exposed:
|
||||
|
||||
```c
|
||||
LDKChannelKeys InMemoryChannelKeys_as_ChannelKeys(const LDKInMemoryChannelKeys *this_arg);
|
||||
```
|
||||
|
||||
#### Enums
|
||||
Rust "unitary" enums are mapped simply as an equivalent C enum; however, some Rust enums have
|
||||
variants which contain payloads. Such enums are mapped automatically by cbindgen as a tag which
|
||||
indicates the type and a union which holds the relevant fields for a given tag. An `X_free` function
|
||||
is provided for the enum as a whole which automatically frees the correct fields for a give tag, and
|
||||
a `Sentinel` tag is provided which causes the free function to do nothing (but which must never
|
||||
appear in an enum when accessed by Rust code). The `Sentinel` tag is used by the C++ wrapper classes
|
||||
to allow moving the ownership of an enum while invalidating the old copy.
|
||||
|
||||
For example, the unitary enum `LDKChannelMonitorUpdateErr` is mapped as follows:
|
||||
```c
|
||||
typedef enum LDKChannelMonitorUpdateErr {
|
||||
/** .. */
|
||||
LDKChannelMonitorUpdateErr_TemporaryFailure,
|
||||
/** .. */
|
||||
LDKChannelMonitorUpdateErr_PermanentFailure,
|
||||
/** .. */
|
||||
LDKChannelMonitorUpdateErr_Sentinel,
|
||||
} LDKChannelMonitorUpdateErr;
|
||||
```
|
||||
|
||||
and the non-unitary enum LDKErrorAction is mapped as follows:
|
||||
```c
|
||||
typedef enum LDKErrorAction_Tag {
|
||||
/** .. */
|
||||
LDKErrorAction_DisconnectPeer,
|
||||
/** .. */
|
||||
LDKErrorAction_IgnoreError,
|
||||
/** .. */
|
||||
LDKErrorAction_SendErrorMessage,
|
||||
/** .. */
|
||||
LDKErrorAction_Sentinel,
|
||||
} LDKErrorAction_Tag;
|
||||
|
||||
typedef struct LDKErrorAction_LDKDisconnectPeer_Body {
|
||||
LDKErrorMessage msg;
|
||||
} LDKErrorAction_LDKDisconnectPeer_Body;
|
||||
|
||||
typedef struct LDKErrorAction_LDKSendErrorMessage_Body {
|
||||
LDKErrorMessage msg;
|
||||
} LDKErrorAction_LDKSendErrorMessage_Body;
|
||||
|
||||
typedef struct LDKErrorAction {
|
||||
LDKErrorAction_Tag tag;
|
||||
union {
|
||||
LDKErrorAction_LDKDisconnectPeer_Body disconnect_peer;
|
||||
LDKErrorAction_LDKSendErrorMessage_Body send_error_message;
|
||||
};
|
||||
} LDKErrorAction;
|
||||
```
|
||||
|
||||
#### Functions
|
||||
Struct member functions are mapped as `Struct_function_name` and take a pointer to the mapped struct
|
||||
as their first argument. Free-standing functions are mapped simply as `function_name` and take the
|
||||
relevant mapped type arguments.
|
||||
|
||||
Functions which return `&OpaqueRustType` and which return `OpaqueRustType` are both mapped to a
|
||||
function returning an owned wrapper struct. The `is_owned` flag (see above) will be set to indicate
|
||||
that the pointed-to Rust object is owned or only a reference. Thus, when implementing a function
|
||||
which Rust will call or calling a Rust function, you should check the Rust documentation for the
|
||||
function to determine whether an owned or referenced object is expected or returned.
|
||||
|
||||
Similarly, when a function takes an `Option<RustType>` as a parameter or a return value, the C type
|
||||
is the same as if it took only `RustType`, with the `inner` field set to NULL to indicate None. For
|
||||
example, `ChannelManager_create_channel` takes an `Option<LDKUserConfig>` not an `LDKUserConfig`,
|
||||
but its definition is:
|
||||
```c
|
||||
MUST_USE_RES ... ChannelManager_create_channel(const LDKChannelManager *this_arg, ..., LDKUserConfig override_config);
|
||||
```
|
||||
|
||||
#### Containers
|
||||
Various containers (Tuples, Vecs, Results, etc) are mapped into C structs of the form
|
||||
`LDKCContainerType_ContainerElementsZ`. Inner fields are often pointers, and in the case of
|
||||
primitive types, these may be allocated in C using the system allocator. See [the Rust docs on your
|
||||
platform's default System allocator](https://doc.rust-lang.org/std/alloc/struct.System.html) for
|
||||
which allocator you must use. Recursive containers are possible, and simply replace the
|
||||
`ContainerElements` part with `InnerContainerType_InnerContainerElementsZ`, eg
|
||||
`LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ` represents a
|
||||
`Result<(Signature, Vec<Signature>), ()>`.
|
||||
|
||||
#### Notes
|
||||
As the bindings are auto-generated, the best resource for documentation on them is the native Rust
|
||||
docs available via `cargo doc` or [docs.rs/lightning](https://docs.rs/lightning).
|
||||
|
||||
The memory model is largely the Rust memory model and not a native C-like memory model. Thus,
|
||||
function parameters are largely only ever passed by reference or by move, with pass-by-copy
|
||||
semantics only applying to primitive types. However, because the underlying types are largely
|
||||
pointers, the same function signature may imply two different memory ownership semantics. Thus, you
|
||||
MUST read the Rust documentation while using the C bindings. For functions which take arguments
|
||||
where ownership is moved to the function scope, the corresponding `X_free` function MUST NOT be
|
||||
called on the object, whereas for all other objects, `X_free` MUST be used to free resources.
|
||||
|
||||
LDK C++ Bindings
|
||||
================
|
||||
|
||||
The C++ bindings available at include/lightningpp.hpp require extern "C" inclusion of lightning.h
|
||||
and rust_types.h first. They represent thin wrappers around the C types which provide a few
|
||||
C++-isms to make memory model correctness easier to achieve. They provide:
|
||||
* automated destructors which call the relevant `X_free` C functions,
|
||||
* move constructors both from C++ classes and the original C struct, with the original object
|
||||
cleared to ensure destruction/`X_free` calls do not cause a double-free.
|
||||
* Move semantics via the () operator, returning the original C struct and clearing the C++ object.
|
||||
This allows calls such as `C_function(cpp_object)` which work as expected with move semantics.
|
||||
|
||||
In general, you should prefer to use the C++ bindings if possible, as they make memory leaks and
|
||||
other violations somewhat easier to avoid. Note that, because the C functions are not redefined in
|
||||
C++, all functions return the C type. Thus, you must bind returned values to the equivalent C++ type
|
||||
(replacing `LDKX` with `LDK::X`) to ensure the destructor is properly run. A demonstration of such
|
||||
usage is available at [demo.cpp](demo.cpp).
|
||||
|
||||
Gotchas
|
||||
=======
|
||||
|
||||
There are a few gotchas around future changes to Rust-Lightning which the bindings may not support.
|
||||
These include:
|
||||
* Any trait method which returns a reference to a struct or inner variable cannot be called in
|
||||
parallel. This is because such functions always return a local variable stored inside the trait,
|
||||
with a call through a function pointer to get the local variable set correctly. Automatically
|
||||
generated setter functions have comments describing the potential race conditions in their
|
||||
definition.
|
||||
|
||||
For example, the `ChannelKeys::pubkeys() -> &ChannelPublicKeys` function is mapped as this:
|
||||
|
||||
```c
|
||||
typedef struct LDKChannelKeys {
|
||||
...
|
||||
LDKChannelPublicKeys pubkeys;
|
||||
/** ... */
|
||||
void (*set_pubkeys)(const LDKChannelKeys*);
|
||||
...
|
||||
} LDKChannelKeys;
|
||||
```
|
||||
|
||||
**It is highly recommended that you test any code which relies on the C (or C++) bindings in
|
||||
valgrind, AddressSanitizer, MemorySanitizer, or other similar tools to ensure correctness.**
|
||||
|
||||
Note that after running `genbindings.sh`, if possible, the static lib in target/debug (eg
|
||||
target/debug/liblightning.a) will be linked with address sanitizer. In order to build against it,
|
||||
you will need to link with `clang` with `-fsanitize=address` with the same version of LLVM as
|
||||
`rustc`'s LLVM. If `genbindings.sh` failed to find a matching `clang` or you are building on an
|
||||
unsupported platform, a warning noting that address sanitizer is not available will be printed.
|
552
lightning-c-bindings/cbindgen.toml
Normal file
552
lightning-c-bindings/cbindgen.toml
Normal file
|
@ -0,0 +1,552 @@
|
|||
# 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
|
||||
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: <stdarg.h>, <stdbool.h>, <stdint.h>, <stdlib.h>, <uchar.h>
|
||||
#
|
||||
# * for C++: <cstdarg>, <cstdint>, <cstdlib>, <new>, <cassert> (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
|
||||
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 `<cassert>` 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"]
|
96
lightning-c-bindings/demo.c
Normal file
96
lightning-c-bindings/demo.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
#include "include/rust_types.h"
|
||||
#include "include/lightning.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void print_log(const void *this_arg, const char *record) {
|
||||
printf("%s", record);
|
||||
}
|
||||
|
||||
uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
|
||||
if (target == LDKConfirmationTarget_Background) {
|
||||
return 253;
|
||||
} else {
|
||||
return 507;
|
||||
}
|
||||
}
|
||||
|
||||
void broadcast_tx(const void *this_arg, LDKTransaction tx) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo, LDKChannelMonitor monitor) {
|
||||
return CResult_NoneChannelMonitorUpdateErrZ_ok();
|
||||
}
|
||||
LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo, LDKChannelMonitorUpdate monitor) {
|
||||
return CResult_NoneChannelMonitorUpdateErrZ_ok();
|
||||
}
|
||||
LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
|
||||
LDKCVec_MonitorEventZ empty_htlc_vec = {
|
||||
.data = NULL,
|
||||
.datalen = 0,
|
||||
};
|
||||
return empty_htlc_vec;
|
||||
}
|
||||
|
||||
int main() {
|
||||
uint8_t node_seed[32];
|
||||
memset(node_seed, 0, 32);
|
||||
|
||||
LDKNetwork net = LDKNetwork_Bitcoin;
|
||||
|
||||
LDKLogger logger = {
|
||||
.this_arg = NULL,
|
||||
.log = print_log,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
LDKFeeEstimator fee_est = {
|
||||
.this_arg = NULL,
|
||||
.get_est_sat_per_1000_weight = get_fee,
|
||||
.free = NULL
|
||||
};
|
||||
|
||||
LDKManyChannelMonitor mon = {
|
||||
.this_arg = NULL,
|
||||
.add_monitor = add_channel_monitor,
|
||||
.update_monitor = update_channel_monitor,
|
||||
.get_and_clear_pending_monitor_events = monitors_pending_monitor_events,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
LDKBroadcasterInterface broadcast = {
|
||||
broadcast.this_arg = NULL,
|
||||
broadcast.broadcast_transaction = broadcast_tx,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
LDKKeysManager keys = KeysManager_new(&node_seed, net, 0, 0);
|
||||
LDKKeysInterface keys_source = KeysManager_as_KeysInterface(&keys);
|
||||
|
||||
LDKUserConfig config = UserConfig_default();
|
||||
|
||||
LDKChannelManager cm = ChannelManager_new(net, fee_est, mon, broadcast, logger, keys_source, config, 0);
|
||||
|
||||
LDKCVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm);
|
||||
assert((unsigned long)channels.data < 4096); // There's an offset, but it should still be an offset against null in the 0 page
|
||||
assert(channels.datalen == 0);
|
||||
CVec_ChannelDetailsZ_free(channels);
|
||||
|
||||
LDKEventsProvider prov = ChannelManager_as_EventsProvider(&cm);
|
||||
LDKCVec_EventZ events = (prov.get_and_clear_pending_events)(prov.this_arg);
|
||||
assert((unsigned long)events.data < 4096); // There's an offset, but it should still be an offset against null in the 0 page
|
||||
assert(events.datalen == 0);
|
||||
|
||||
ChannelManager_free(cm);
|
||||
KeysManager_free(keys);
|
||||
|
||||
// Check that passing empty vecs to rust doesn't blow it up:
|
||||
LDKCVec_MonitorEventZ empty_htlc_vec = {
|
||||
.data = NULL,
|
||||
.datalen = 0,
|
||||
};
|
||||
CVec_MonitorEventZ_free(empty_htlc_vec);
|
||||
}
|
556
lightning-c-bindings/demo.cpp
Normal file
556
lightning-c-bindings/demo.cpp
Normal file
|
@ -0,0 +1,556 @@
|
|||
extern "C" {
|
||||
#include "include/rust_types.h"
|
||||
#include "include/lightning.h"
|
||||
}
|
||||
#include "include/lightningpp.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
const uint8_t valid_node_announcement[] = {
|
||||
0x94, 0xe4, 0xf5, 0x61, 0x41, 0x24, 0x7d, 0x90, 0x23, 0xa0, 0xc8, 0x34, 0x8c, 0xc4, 0xca, 0x51,
|
||||
0xd8, 0x17, 0x59, 0xff, 0x7d, 0xac, 0x8c, 0x9b, 0x63, 0x29, 0x1c, 0xe6, 0x12, 0x12, 0x93, 0xbd,
|
||||
0x66, 0x4d, 0x6b, 0x9c, 0xfb, 0x35, 0xda, 0x16, 0x06, 0x3d, 0xf0, 0x8f, 0x8a, 0x39, 0x99, 0xa2,
|
||||
0xf2, 0x5d, 0x12, 0x0f, 0x2b, 0x42, 0x1b, 0x8b, 0x9a, 0xfe, 0x33, 0x0c, 0xeb, 0x33, 0x5e, 0x52,
|
||||
0xee, 0x99, 0xa1, 0x07, 0x06, 0xed, 0xf8, 0x48, 0x7a, 0xc6, 0xe5, 0xf5, 0x5e, 0x01, 0x3a, 0x41,
|
||||
0x2f, 0x18, 0x94, 0x8a, 0x3b, 0x0a, 0x52, 0x3f, 0xbf, 0x61, 0xa9, 0xc5, 0x4f, 0x70, 0xee, 0xb8,
|
||||
0x79, 0x23, 0xbb, 0x1a, 0x44, 0x7d, 0x91, 0xe6, 0x2a, 0xbc, 0xa1, 0x07, 0xbc, 0x65, 0x3b, 0x02,
|
||||
0xd9, 0x1d, 0xb2, 0xf2, 0x3a, 0xcb, 0x75, 0x79, 0xc6, 0x66, 0xd8, 0xc1, 0x71, 0x29, 0xdf, 0x04,
|
||||
0x60, 0xf4, 0xbf, 0x07, 0x7b, 0xb9, 0xc2, 0x11, 0x94, 0x6a, 0x28, 0xc2, 0xdd, 0xd8, 0x7b, 0x44,
|
||||
0x8f, 0x08, 0xe3, 0xc8, 0xd8, 0xf4, 0x81, 0xb0, 0x9f, 0x94, 0xcb, 0xc8, 0xc1, 0x3c, 0xc2, 0x6e,
|
||||
0x31, 0x26, 0xfc, 0x33, 0x16, 0x3b, 0xe0, 0xde, 0xa1, 0x16, 0x21, 0x9f, 0x89, 0xdd, 0x97, 0xa4,
|
||||
0x41, 0xf2, 0x9f, 0x19, 0xb1, 0xae, 0x82, 0xf7, 0x85, 0x9a, 0xb7, 0x8f, 0xb7, 0x52, 0x7a, 0x72,
|
||||
0xf1, 0x5e, 0x89, 0xe1, 0x8a, 0xcd, 0x40, 0xb5, 0x8e, 0xc3, 0xca, 0x42, 0x76, 0xa3, 0x6e, 0x1b,
|
||||
0xf4, 0x87, 0x35, 0x30, 0x58, 0x43, 0x04, 0xd9, 0x2c, 0x50, 0x54, 0x55, 0x47, 0x6f, 0x70, 0x9b,
|
||||
0x42, 0x1f, 0x91, 0xfc, 0xa1, 0xdb, 0x72, 0x53, 0x96, 0xc8, 0xe5, 0xcd, 0x0e, 0xcb, 0xa0, 0xfe,
|
||||
0x6b, 0x08, 0x77, 0x48, 0xb7, 0xad, 0x4a, 0x69, 0x7c, 0xdc, 0xd8, 0x04, 0x28, 0x35, 0x9b, 0x73,
|
||||
0x00, 0x00, 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce,
|
||||
0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82,
|
||||
0x09, 0x67, 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa,
|
||||
0x1d, 0x64, 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, 0x2c, 0x03, 0x5c, 0x4e, 0x0d, 0xec,
|
||||
0x72, 0x15, 0xe2, 0x68, 0x33, 0x93, 0x87, 0x30, 0xe5, 0xe5, 0x05, 0xaa, 0x62, 0x50, 0x4d, 0xa8,
|
||||
0x5b, 0xa5, 0x71, 0x06, 0xa4, 0x6b, 0x5a, 0x24, 0x04, 0xfc, 0x9d, 0x8e, 0x02, 0xba, 0x72, 0xa6,
|
||||
0xe8, 0xba, 0x53, 0xe8, 0xb9, 0x71, 0xad, 0x0c, 0x98, 0x23, 0x96, 0x8a, 0xef, 0x4d, 0x78, 0xce,
|
||||
0x8a, 0xf2, 0x55, 0xab, 0x43, 0xdf, 0xf8, 0x30, 0x03, 0xc9, 0x02, 0xfb, 0x8d, 0x02, 0x16, 0x34,
|
||||
0x5b, 0xf8, 0x31, 0x16, 0x4a, 0x03, 0x75, 0x8e, 0xae, 0xa5, 0xe8, 0xb6, 0x6f, 0xee, 0x2b, 0xe7,
|
||||
0x71, 0x0b, 0x8f, 0x19, 0x0e, 0xe8, 0x80, 0x24, 0x90, 0x32, 0xa2, 0x9e, 0xd6, 0x6e
|
||||
};
|
||||
|
||||
// A simple block containing only one transaction (which is the channel-open transaction for the
|
||||
// channel we'll create). This was originally created by printing additional data in a simple
|
||||
// rust-lightning unit test.
|
||||
const uint8_t channel_open_block[] = {
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xa2, 0x47, 0xd2, 0xf8, 0xd4, 0xe0, 0x6a, 0x3f, 0xf9, 0x7a, 0x9a, 0x34,
|
||||
0xbb, 0xa9, 0x96, 0xde, 0x63, 0x84, 0x5a, 0xce, 0xcf, 0x98, 0xb8, 0xbb, 0x75, 0x4c, 0x4f, 0x7d,
|
||||
0xee, 0x4c, 0xa9, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x20, 0x12, 0x70,
|
||||
0x44, 0x41, 0x40, 0xaf, 0xc5, 0x72, 0x97, 0xc8, 0x69, 0xba, 0x04, 0xdb, 0x28, 0x7b, 0xd7, 0x32,
|
||||
0x07, 0x33, 0x3a, 0x4a, 0xc2, 0xc5, 0x56, 0x06, 0x05, 0x65, 0xd7, 0xa8, 0xcf, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data.
|
||||
const uint8_t *channel_open_tx = channel_open_block + 81;
|
||||
const uint8_t channel_open_txid[] = {
|
||||
0x5f, 0xa9, 0x4c, 0xee, 0x7d, 0x4f, 0x4c, 0x75, 0xbb, 0xb8, 0x98, 0xcf, 0xce, 0x5a, 0x84, 0x63,
|
||||
0xde, 0x96, 0xa9, 0xbb, 0x34, 0x9a, 0x7a, 0xf9, 0x3f, 0x6a, 0xe0, 0xd4, 0xf8, 0xd2, 0x47, 0xa2
|
||||
};
|
||||
|
||||
// Two blocks built on top of channel_open_block:
|
||||
const uint8_t block_1[] = {
|
||||
0x01, 0x00, 0x00, 0x00, 0x65, 0x8e, 0xf1, 0x90, 0x88, 0xfa, 0x13, 0x9c, 0x6a, 0xea, 0xf7, 0xc1,
|
||||
0x5a, 0xdd, 0x52, 0x4d, 0x3c, 0x48, 0x03, 0xb3, 0x9b, 0x25, 0x4f, 0x02, 0x79, 0x05, 0x90, 0xe0,
|
||||
0xc4, 0x8d, 0xa0, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00
|
||||
};
|
||||
const uint8_t block_2[] = {
|
||||
0x01, 0x00, 0x00, 0x00, 0xf2, 0x08, 0x87, 0x51, 0xcb, 0xb1, 0x1a, 0x51, 0x76, 0x01, 0x6c, 0x5d,
|
||||
0x76, 0x26, 0x54, 0x6f, 0xd9, 0xbd, 0xa6, 0xa5, 0xe9, 0x4b, 0x21, 0x6e, 0xda, 0xa3, 0x64, 0x23,
|
||||
0xcd, 0xf1, 0xe2, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00
|
||||
};
|
||||
|
||||
const LDKThirtyTwoBytes payment_preimage_1 = {
|
||||
.data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }
|
||||
};
|
||||
const LDKThirtyTwoBytes payment_hash_1 = {
|
||||
.data = {
|
||||
0xdc, 0xb1, 0xac, 0x4a, 0x5d, 0xe3, 0x70, 0xca, 0xd0, 0x91, 0xc1, 0x3f, 0x13, 0xae, 0xe2, 0xf9,
|
||||
0x36, 0xc2, 0x78, 0xfa, 0x05, 0xd2, 0x64, 0x65, 0x3c, 0x0c, 0x13, 0x21, 0x85, 0x2a, 0x35, 0xe8
|
||||
}
|
||||
};
|
||||
|
||||
void print_log(const void *this_arg, const char *record) {
|
||||
printf("%p - %s\n", this_arg, record);
|
||||
}
|
||||
|
||||
uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
|
||||
if (target == LDKConfirmationTarget_Background) {
|
||||
return 253;
|
||||
} else {
|
||||
return 507;
|
||||
}
|
||||
// Note that we don't call _free() on target, but that's OK, its unitary
|
||||
}
|
||||
|
||||
static int num_txs_broadcasted = 0; // Technically a race, but ints are atomic on x86
|
||||
void broadcast_tx(const void *this_arg, LDKTransaction tx) {
|
||||
num_txs_broadcasted += 1;
|
||||
//TODO
|
||||
}
|
||||
|
||||
struct NodeMonitors {
|
||||
std::mutex mut;
|
||||
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
|
||||
LDKChainWatchInterfaceUtil* watch_util;
|
||||
LDKLogger* logger;
|
||||
};
|
||||
void NodeMonitors_free(void *this_arg) {
|
||||
NodeMonitors* arg = (NodeMonitors*) this_arg;
|
||||
delete arg;
|
||||
}
|
||||
|
||||
LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
|
||||
// First bind the args to C++ objects so they auto-free
|
||||
LDK::ChannelMonitor mon(std::move(monitor_arg));
|
||||
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
|
||||
|
||||
NodeMonitors* arg = (NodeMonitors*) this_arg;
|
||||
std::unique_lock<std::mutex> l(arg->mut);
|
||||
|
||||
LDK::ChainWatchInterface watch = ChainWatchInterfaceUtil_as_ChainWatchInterface(arg->watch_util);
|
||||
LDK::C2Tuple_OutPointScriptZ funding_info = ChannelMonitor_get_funding_txo(&mon);
|
||||
LDKThirtyTwoBytes funding_txid;
|
||||
memcpy(funding_txid.data, OutPoint_get_txid(funding_info->a), 32);
|
||||
LDK::C2Tuple_Txidu32Z outpoint(C2Tuple_Txidu32Z_new(funding_txid, OutPoint_get_index(funding_info->a)));
|
||||
watch->install_watch_outpoint(watch->this_arg, outpoint, LDKu8slice {
|
||||
.data = funding_info->b->data,
|
||||
.datalen = funding_info->b->datalen,
|
||||
});
|
||||
watch->install_watch_tx(watch->this_arg, &funding_txid.data, LDKu8slice {
|
||||
.data = funding_info->b->data,
|
||||
.datalen = funding_info->b->datalen,
|
||||
});
|
||||
arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
|
||||
return CResult_NoneChannelMonitorUpdateErrZ_ok();
|
||||
}
|
||||
static int mons_updated = 0; // Technically a race, but ints are atomic on x86.
|
||||
LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
|
||||
// First bind the args to C++ objects so they auto-free
|
||||
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
|
||||
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
|
||||
|
||||
NodeMonitors* arg = (NodeMonitors*) this_arg;
|
||||
std::unique_lock<std::mutex> l(arg->mut);
|
||||
|
||||
bool updated = false;
|
||||
for (auto& mon : arg->mons) {
|
||||
if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
|
||||
!memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
|
||||
updated = true;
|
||||
LDKBroadcasterInterface broadcaster = {
|
||||
.broadcast_transaction = broadcast_tx,
|
||||
};
|
||||
LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, update, &broadcaster, arg->logger);
|
||||
assert(res->result_ok);
|
||||
}
|
||||
}
|
||||
assert(updated);
|
||||
|
||||
mons_updated += 1;
|
||||
return CResult_NoneChannelMonitorUpdateErrZ_ok();
|
||||
}
|
||||
LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
|
||||
NodeMonitors* arg = (NodeMonitors*) this_arg;
|
||||
std::unique_lock<std::mutex> l(arg->mut);
|
||||
|
||||
if (arg->mons.size() == 0) {
|
||||
return LDKCVec_MonitorEventZ {
|
||||
.data = NULL,
|
||||
.datalen = 0,
|
||||
};
|
||||
} else {
|
||||
// We only ever actually have one channel per node, plus concatenating two
|
||||
// Rust Vecs to each other from C++ will require a bit of effort.
|
||||
assert(arg->mons.size() == 1);
|
||||
return ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
|
||||
return write((int)((long)this_arg), data.data, data.datalen);
|
||||
}
|
||||
void sock_disconnect_socket(void *this_arg) {
|
||||
close((int)((long)this_arg));
|
||||
}
|
||||
bool sock_eq(const void *this_arg, const void *other_arg) {
|
||||
return this_arg == other_arg;
|
||||
}
|
||||
uint64_t sock_hash(const void *this_arg) {
|
||||
return (uint64_t)this_arg;
|
||||
}
|
||||
void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
|
||||
unsigned char buf[1024];
|
||||
LDKu8slice data;
|
||||
data.data = buf;
|
||||
ssize_t readlen = 0;
|
||||
while ((readlen = read(rdfd, buf, 1024)) > 0) {
|
||||
data.datalen = readlen;
|
||||
LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
|
||||
if (!res->result_ok) {
|
||||
peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
|
||||
return;
|
||||
}
|
||||
PeerManager_process_events(pm);
|
||||
}
|
||||
PeerManager_socket_disconnected(&*pm, peer_descriptor);
|
||||
}
|
||||
|
||||
int main() {
|
||||
uint8_t node_seed[32];
|
||||
memset(&node_seed, 0, 32);
|
||||
|
||||
LDKPublicKey null_pk;
|
||||
memset(&null_pk, 0, sizeof(null_pk));
|
||||
|
||||
LDKNetwork network = LDKNetwork_Testnet;
|
||||
|
||||
// Trait implementations:
|
||||
LDKFeeEstimator fee_est {
|
||||
.this_arg = NULL,
|
||||
.get_est_sat_per_1000_weight = get_fee,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
LDKBroadcasterInterface broadcast {
|
||||
.this_arg = NULL,
|
||||
.broadcast_transaction = broadcast_tx,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
// Instantiate classes for node 1:
|
||||
|
||||
LDKLogger logger1 {
|
||||
.this_arg = (void*)1,
|
||||
.log = print_log,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
LDK::ChainWatchInterfaceUtil chain1 = ChainWatchInterfaceUtil_new(network);
|
||||
LDK::BlockNotifier blocks1 = BlockNotifier_new(ChainWatchInterfaceUtil_as_ChainWatchInterface(&chain1));
|
||||
|
||||
LDKManyChannelMonitor mon1 {
|
||||
.this_arg = new NodeMonitors { .watch_util = &chain1, .logger = &logger1 },
|
||||
.add_monitor = add_channel_monitor,
|
||||
.update_monitor = update_channel_monitor,
|
||||
.get_and_clear_pending_monitor_events = monitors_pending_monitor_events,
|
||||
.free = NodeMonitors_free,
|
||||
};
|
||||
|
||||
LDK::KeysManager keys1 = KeysManager_new(&node_seed, network, 0, 0);
|
||||
LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
|
||||
LDKSecretKey node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
|
||||
|
||||
LDK::UserConfig config1 = UserConfig_default();
|
||||
|
||||
LDK::ChannelManager cm1 = ChannelManager_new(network, fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), config1, 0);
|
||||
BlockNotifier_register_listener(&blocks1, ChannelManager_as_ChainListener(&cm1));
|
||||
|
||||
LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
|
||||
assert(channels->datalen == 0);
|
||||
|
||||
LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(ChainWatchInterfaceUtil_as_ChainWatchInterface(&chain1), logger1);
|
||||
|
||||
LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
|
||||
|
||||
LDKThirtyTwoBytes random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
|
||||
LDK::PeerManager net1 = PeerManager_new(msg_handler1, node_secret1, &random_bytes.data, logger1);
|
||||
|
||||
// Demo getting a channel key and check that its returning real pubkeys:
|
||||
LDK::ChannelKeys chan_keys1 = keys_source1->get_channel_keys(keys_source1->this_arg, false, 42);
|
||||
chan_keys1->set_pubkeys(&chan_keys1); // Make sure pubkeys is defined
|
||||
LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_keys1->pubkeys);
|
||||
assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
|
||||
|
||||
// Instantiate classes for node 2:
|
||||
|
||||
LDKLogger logger2 {
|
||||
.this_arg = (void*)2,
|
||||
.log = print_log,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
LDK::ChainWatchInterfaceUtil chain2 = ChainWatchInterfaceUtil_new(network);
|
||||
LDK::BlockNotifier blocks2 = BlockNotifier_new(ChainWatchInterfaceUtil_as_ChainWatchInterface(&chain2));
|
||||
|
||||
LDKManyChannelMonitor mon2 {
|
||||
.this_arg = new NodeMonitors { .watch_util = &chain2, .logger = &logger2 },
|
||||
.add_monitor = add_channel_monitor,
|
||||
.update_monitor = update_channel_monitor,
|
||||
.get_and_clear_pending_monitor_events = monitors_pending_monitor_events,
|
||||
.free = NodeMonitors_free,
|
||||
};
|
||||
|
||||
memset(&node_seed, 1, 32);
|
||||
LDK::KeysManager keys2 = KeysManager_new(&node_seed, network, 0, 0);
|
||||
LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
|
||||
LDKSecretKey node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
|
||||
|
||||
LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
|
||||
ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
|
||||
LDK::UserConfig config2 = UserConfig_default();
|
||||
UserConfig_set_own_channel_config(&config2, handshake_config2);
|
||||
|
||||
LDK::ChannelManager cm2 = ChannelManager_new(network, fee_est, mon2, broadcast, logger2, KeysManager_as_KeysInterface(&keys2), config2, 0);
|
||||
BlockNotifier_register_listener(&blocks2, ChannelManager_as_ChainListener(&cm2));
|
||||
|
||||
LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
|
||||
assert(channels2->datalen == 0);
|
||||
|
||||
LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(ChainWatchInterfaceUtil_as_ChainWatchInterface(&chain2), logger2);
|
||||
LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
|
||||
LDK::ChannelAnnouncement chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
|
||||
LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, &chan_ann);
|
||||
assert(ann_res->result_ok);
|
||||
|
||||
LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), net_msgs2);
|
||||
|
||||
LDKThirtyTwoBytes random_bytes2 = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
|
||||
LDK::PeerManager net2 = PeerManager_new(msg_handler2, node_secret2, &random_bytes2.data, logger2);
|
||||
|
||||
// Open a connection!
|
||||
int pipefds_1_to_2[2];
|
||||
int pipefds_2_to_1[2];
|
||||
assert(!pipe(pipefds_1_to_2));
|
||||
assert(!pipe(pipefds_2_to_1));
|
||||
|
||||
LDKSocketDescriptor sock1 {
|
||||
.this_arg = (void*)(long)pipefds_1_to_2[1],
|
||||
.send_data = sock_send_data,
|
||||
.disconnect_socket = sock_disconnect_socket,
|
||||
.eq = sock_eq,
|
||||
.hash = sock_hash,
|
||||
.clone = NULL,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
LDKSocketDescriptor sock2 {
|
||||
.this_arg = (void*)(long)pipefds_2_to_1[1],
|
||||
.send_data = sock_send_data,
|
||||
.disconnect_socket = sock_disconnect_socket,
|
||||
.eq = sock_eq,
|
||||
.hash = sock_hash,
|
||||
.clone = NULL,
|
||||
.free = NULL,
|
||||
};
|
||||
|
||||
std::thread t1(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
|
||||
std::thread t2(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
|
||||
|
||||
// Note that we have to bind the result to a C++ class to make sure it gets free'd
|
||||
LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
|
||||
assert(con_res->result_ok);
|
||||
LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
|
||||
assert(con_res2->result_ok);
|
||||
|
||||
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
|
||||
assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
|
||||
|
||||
while (true) {
|
||||
// Wait for the initial handshakes to complete...
|
||||
LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
|
||||
LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
|
||||
if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
// Note that we have to bind the result to a C++ class to make sure it gets free'd
|
||||
LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, config1);
|
||||
assert(res->result_ok);
|
||||
PeerManager_process_events(&net1);
|
||||
|
||||
LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
|
||||
assert(new_channels->datalen == 1);
|
||||
LDKPublicKey chan_open_pk = ChannelDetails_get_remote_network_id(&new_channels->data[0]);
|
||||
assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
|
||||
|
||||
while (true) {
|
||||
LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
|
||||
if (new_channels_2->datalen == 1) {
|
||||
// Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
|
||||
const LDK::InitFeatures init_feats = ChannelDetails_get_counterparty_features(&new_channels_2->data[0]);
|
||||
assert(init_feats->inner != NULL);
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
|
||||
while (true) {
|
||||
LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
|
||||
if (events->datalen == 1) {
|
||||
assert(events->data[0].tag == LDKEvent_FundingGenerationReady);
|
||||
assert(events->data[0].funding_generation_ready.user_channel_id == 42);
|
||||
assert(events->data[0].funding_generation_ready.channel_value_satoshis == 40000);
|
||||
assert(events->data[0].funding_generation_ready.output_script.datalen == 34);
|
||||
assert(!memcmp(events->data[0].funding_generation_ready.output_script.data, channel_open_tx + 58, 34));
|
||||
LDKThirtyTwoBytes txid;
|
||||
for (int i = 0; i < 32; i++) { txid.data[i] = channel_open_txid[31-i]; }
|
||||
LDK::OutPoint outp = OutPoint_new(txid, 0);
|
||||
ChannelManager_funding_transaction_generated(&cm1, &events->data[0].funding_generation_ready.temporary_channel_id.data, outp);
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
// We observe when the funding signed messages have been exchanged by
|
||||
// waiting for two monitors to be registered.
|
||||
PeerManager_process_events(&net1);
|
||||
while (true) {
|
||||
LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
|
||||
if (events->datalen == 1) {
|
||||
assert(events->data[0].tag == LDKEvent_FundingBroadcastSafe);
|
||||
assert(events->data[0].funding_broadcast_safe.user_channel_id == 42);
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
BlockNotifier_block_connected(&blocks1, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
|
||||
BlockNotifier_block_connected(&blocks2, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
|
||||
|
||||
BlockNotifier_block_connected(&blocks1, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
|
||||
BlockNotifier_block_connected(&blocks2, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
|
||||
|
||||
BlockNotifier_block_connected(&blocks1, LDKu8slice { .data = block_2, .datalen = sizeof(block_2) }, 3);
|
||||
BlockNotifier_block_connected(&blocks2, LDKu8slice { .data = block_2, .datalen = sizeof(block_2) }, 3);
|
||||
|
||||
PeerManager_process_events(&net1);
|
||||
PeerManager_process_events(&net2);
|
||||
|
||||
// Now send funds from 1 to 2!
|
||||
while (true) {
|
||||
LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
|
||||
if (outbound_channels->datalen == 1) {
|
||||
const LDKChannelDetails *channel = &outbound_channels->data[0];
|
||||
// Note that the channel ID is the same as the channel txid reversed as the output index is 0
|
||||
uint8_t expected_chan_id[32];
|
||||
for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
|
||||
assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
|
||||
assert(!memcmp(ChannelDetails_get_remote_network_id(channel).compressed_form,
|
||||
ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
|
||||
assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
|
||||
// We opened the channel with 1000 push_msat:
|
||||
assert(ChannelDetails_get_outbound_capacity_msat(channel) == 40000*1000 - 1000);
|
||||
assert(ChannelDetails_get_inbound_capacity_msat(channel) == 1000);
|
||||
assert(ChannelDetails_get_is_live(channel));
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
|
||||
LDKThirtyTwoBytes payment_secret;
|
||||
memset(payment_secret.data, 0x42, 32);
|
||||
{
|
||||
LDK::LockedNetworkGraph graph_2_locked = NetGraphMsgHandler_read_locked_graph(&net_graph2);
|
||||
LDK::NetworkGraph graph_2_ref = LockedNetworkGraph_graph(&graph_2_locked);
|
||||
LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), &outbound_channels, LDKCVec_RouteHintZ {
|
||||
.data = NULL, .datalen = 0
|
||||
}, 5000, 10, logger1);
|
||||
assert(route->result_ok);
|
||||
LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash_1, payment_secret);
|
||||
assert(send_res->result_ok);
|
||||
}
|
||||
|
||||
mons_updated = 0;
|
||||
PeerManager_process_events(&net1);
|
||||
while (mons_updated != 4) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
// Check that we received the payment!
|
||||
LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
|
||||
while (true) {
|
||||
LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg);
|
||||
if (events->datalen == 1) {
|
||||
assert(events->data[0].tag == LDKEvent_PendingHTLCsForwardable);
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
ChannelManager_process_pending_htlc_forwards(&cm2);
|
||||
PeerManager_process_events(&net2);
|
||||
|
||||
mons_updated = 0;
|
||||
{
|
||||
LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg);
|
||||
assert(events->datalen == 1);
|
||||
assert(events->data[0].tag == LDKEvent_PaymentReceived);
|
||||
assert(!memcmp(events->data[0].payment_received.payment_hash.data, payment_hash_1.data, 32));
|
||||
assert(!memcmp(events->data[0].payment_received.payment_secret.data, payment_secret.data, 32));
|
||||
assert(events->data[0].payment_received.amt == 5000);
|
||||
assert(ChannelManager_claim_funds(&cm2, payment_preimage_1, payment_secret, 5000));
|
||||
}
|
||||
PeerManager_process_events(&net2);
|
||||
// Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
|
||||
while (mons_updated != 5) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
{
|
||||
LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
|
||||
assert(events->datalen == 1);
|
||||
assert(events->data[0].tag == LDKEvent_PaymentSent);
|
||||
assert(!memcmp(events->data[0].payment_sent.payment_preimage.data, payment_preimage_1.data, 32));
|
||||
}
|
||||
|
||||
// Close the channel.
|
||||
uint8_t chan_id[32];
|
||||
for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
|
||||
LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
|
||||
assert(close_res->result_ok);
|
||||
PeerManager_process_events(&net1);
|
||||
num_txs_broadcasted = 0;
|
||||
while (num_txs_broadcasted != 2) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
|
||||
assert(chans_after_close1->datalen == 0);
|
||||
LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
|
||||
assert(chans_after_close2->datalen == 0);
|
||||
|
||||
close(pipefds_1_to_2[0]);
|
||||
close(pipefds_2_to_1[0]);
|
||||
close(pipefds_1_to_2[1]);
|
||||
close(pipefds_2_to_1[1]);
|
||||
t1.join();
|
||||
t2.join();
|
||||
|
||||
// Few extra random tests:
|
||||
LDKSecretKey sk;
|
||||
memset(&sk, 42, 32);
|
||||
LDKC2Tuple_u64u64Z kdiv_params;
|
||||
kdiv_params.a = (uint64_t*) malloc(8);
|
||||
kdiv_params.b = (uint64_t*) malloc(8);
|
||||
*kdiv_params.a = 42;
|
||||
*kdiv_params.b = 42;
|
||||
LDK::InMemoryChannelKeys keys = InMemoryChannelKeys_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);
|
||||
}
|
6716
lightning-c-bindings/include/lightning.h
Normal file
6716
lightning-c-bindings/include/lightning.h
Normal file
File diff suppressed because it is too large
Load diff
1987
lightning-c-bindings/include/lightningpp.hpp
Normal file
1987
lightning-c-bindings/include/lightningpp.hpp
Normal file
File diff suppressed because it is too large
Load diff
154
lightning-c-bindings/include/rust_types.h
Normal file
154
lightning-c-bindings/include/rust_types.h
Normal file
|
@ -0,0 +1,154 @@
|
|||
#if defined(__GNUC__)
|
||||
#define MUST_USE_STRUCT __attribute__((warn_unused))
|
||||
#else
|
||||
#define MUST_USE_STRUCT
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
#define MUST_USE_RES __attribute__((warn_unused_result))
|
||||
#else
|
||||
#define MUST_USE_RES
|
||||
#endif
|
||||
struct nativeChannelHandshakeConfigOpaque;
|
||||
typedef struct nativeChannelHandshakeConfigOpaque LDKnativeChannelHandshakeConfig;
|
||||
struct nativeChannelHandshakeLimitsOpaque;
|
||||
typedef struct nativeChannelHandshakeLimitsOpaque LDKnativeChannelHandshakeLimits;
|
||||
struct nativeChannelConfigOpaque;
|
||||
typedef struct nativeChannelConfigOpaque LDKnativeChannelConfig;
|
||||
struct nativeUserConfigOpaque;
|
||||
typedef struct nativeUserConfigOpaque LDKnativeUserConfig;
|
||||
struct nativeChainWatchedUtilOpaque;
|
||||
typedef struct nativeChainWatchedUtilOpaque LDKnativeChainWatchedUtil;
|
||||
struct nativeBlockNotifierOpaque;
|
||||
typedef struct nativeBlockNotifierOpaque LDKnativeBlockNotifier;
|
||||
struct nativeChainWatchInterfaceUtilOpaque;
|
||||
typedef struct nativeChainWatchInterfaceUtilOpaque LDKnativeChainWatchInterfaceUtil;
|
||||
struct nativeOutPointOpaque;
|
||||
typedef struct nativeOutPointOpaque LDKnativeOutPoint;
|
||||
struct LDKChannelKeys;
|
||||
typedef struct LDKChannelKeys LDKChannelKeys;
|
||||
struct nativeInMemoryChannelKeysOpaque;
|
||||
typedef struct nativeInMemoryChannelKeysOpaque LDKnativeInMemoryChannelKeys;
|
||||
struct nativeKeysManagerOpaque;
|
||||
typedef struct nativeKeysManagerOpaque LDKnativeKeysManager;
|
||||
struct nativeChannelManagerOpaque;
|
||||
typedef struct nativeChannelManagerOpaque LDKnativeChannelManager;
|
||||
struct nativeChannelDetailsOpaque;
|
||||
typedef struct nativeChannelDetailsOpaque LDKnativeChannelDetails;
|
||||
struct nativePaymentSendFailureOpaque;
|
||||
typedef struct nativePaymentSendFailureOpaque LDKnativePaymentSendFailure;
|
||||
struct nativeChannelManagerReadArgsOpaque;
|
||||
typedef struct nativeChannelManagerReadArgsOpaque LDKnativeChannelManagerReadArgs;
|
||||
struct nativeChannelMonitorUpdateOpaque;
|
||||
typedef struct nativeChannelMonitorUpdateOpaque LDKnativeChannelMonitorUpdate;
|
||||
struct nativeMonitorUpdateErrorOpaque;
|
||||
typedef struct nativeMonitorUpdateErrorOpaque LDKnativeMonitorUpdateError;
|
||||
struct nativeMonitorEventOpaque;
|
||||
typedef struct nativeMonitorEventOpaque LDKnativeMonitorEvent;
|
||||
struct nativeHTLCUpdateOpaque;
|
||||
typedef struct nativeHTLCUpdateOpaque LDKnativeHTLCUpdate;
|
||||
struct nativeChannelMonitorOpaque;
|
||||
typedef struct nativeChannelMonitorOpaque LDKnativeChannelMonitor;
|
||||
struct nativeDecodeErrorOpaque;
|
||||
typedef struct nativeDecodeErrorOpaque LDKnativeDecodeError;
|
||||
struct nativeInitOpaque;
|
||||
typedef struct nativeInitOpaque LDKnativeInit;
|
||||
struct nativeErrorMessageOpaque;
|
||||
typedef struct nativeErrorMessageOpaque LDKnativeErrorMessage;
|
||||
struct nativePingOpaque;
|
||||
typedef struct nativePingOpaque LDKnativePing;
|
||||
struct nativePongOpaque;
|
||||
typedef struct nativePongOpaque LDKnativePong;
|
||||
struct nativeOpenChannelOpaque;
|
||||
typedef struct nativeOpenChannelOpaque LDKnativeOpenChannel;
|
||||
struct nativeAcceptChannelOpaque;
|
||||
typedef struct nativeAcceptChannelOpaque LDKnativeAcceptChannel;
|
||||
struct nativeFundingCreatedOpaque;
|
||||
typedef struct nativeFundingCreatedOpaque LDKnativeFundingCreated;
|
||||
struct nativeFundingSignedOpaque;
|
||||
typedef struct nativeFundingSignedOpaque LDKnativeFundingSigned;
|
||||
struct nativeFundingLockedOpaque;
|
||||
typedef struct nativeFundingLockedOpaque LDKnativeFundingLocked;
|
||||
struct nativeShutdownOpaque;
|
||||
typedef struct nativeShutdownOpaque LDKnativeShutdown;
|
||||
struct nativeClosingSignedOpaque;
|
||||
typedef struct nativeClosingSignedOpaque LDKnativeClosingSigned;
|
||||
struct nativeUpdateAddHTLCOpaque;
|
||||
typedef struct nativeUpdateAddHTLCOpaque LDKnativeUpdateAddHTLC;
|
||||
struct nativeUpdateFulfillHTLCOpaque;
|
||||
typedef struct nativeUpdateFulfillHTLCOpaque LDKnativeUpdateFulfillHTLC;
|
||||
struct nativeUpdateFailHTLCOpaque;
|
||||
typedef struct nativeUpdateFailHTLCOpaque LDKnativeUpdateFailHTLC;
|
||||
struct nativeUpdateFailMalformedHTLCOpaque;
|
||||
typedef struct nativeUpdateFailMalformedHTLCOpaque LDKnativeUpdateFailMalformedHTLC;
|
||||
struct nativeCommitmentSignedOpaque;
|
||||
typedef struct nativeCommitmentSignedOpaque LDKnativeCommitmentSigned;
|
||||
struct nativeRevokeAndACKOpaque;
|
||||
typedef struct nativeRevokeAndACKOpaque LDKnativeRevokeAndACK;
|
||||
struct nativeUpdateFeeOpaque;
|
||||
typedef struct nativeUpdateFeeOpaque LDKnativeUpdateFee;
|
||||
struct nativeDataLossProtectOpaque;
|
||||
typedef struct nativeDataLossProtectOpaque LDKnativeDataLossProtect;
|
||||
struct nativeChannelReestablishOpaque;
|
||||
typedef struct nativeChannelReestablishOpaque LDKnativeChannelReestablish;
|
||||
struct nativeAnnouncementSignaturesOpaque;
|
||||
typedef struct nativeAnnouncementSignaturesOpaque LDKnativeAnnouncementSignatures;
|
||||
struct nativeUnsignedNodeAnnouncementOpaque;
|
||||
typedef struct nativeUnsignedNodeAnnouncementOpaque LDKnativeUnsignedNodeAnnouncement;
|
||||
struct nativeNodeAnnouncementOpaque;
|
||||
typedef struct nativeNodeAnnouncementOpaque LDKnativeNodeAnnouncement;
|
||||
struct nativeUnsignedChannelAnnouncementOpaque;
|
||||
typedef struct nativeUnsignedChannelAnnouncementOpaque LDKnativeUnsignedChannelAnnouncement;
|
||||
struct nativeChannelAnnouncementOpaque;
|
||||
typedef struct nativeChannelAnnouncementOpaque LDKnativeChannelAnnouncement;
|
||||
struct nativeUnsignedChannelUpdateOpaque;
|
||||
typedef struct nativeUnsignedChannelUpdateOpaque LDKnativeUnsignedChannelUpdate;
|
||||
struct nativeChannelUpdateOpaque;
|
||||
typedef struct nativeChannelUpdateOpaque LDKnativeChannelUpdate;
|
||||
struct nativeLightningErrorOpaque;
|
||||
typedef struct nativeLightningErrorOpaque LDKnativeLightningError;
|
||||
struct nativeCommitmentUpdateOpaque;
|
||||
typedef struct nativeCommitmentUpdateOpaque LDKnativeCommitmentUpdate;
|
||||
struct nativeMessageHandlerOpaque;
|
||||
typedef struct nativeMessageHandlerOpaque LDKnativeMessageHandler;
|
||||
struct nativePeerHandleErrorOpaque;
|
||||
typedef struct nativePeerHandleErrorOpaque LDKnativePeerHandleError;
|
||||
struct nativePeerManagerOpaque;
|
||||
typedef struct nativePeerManagerOpaque LDKnativePeerManager;
|
||||
struct nativeTxCreationKeysOpaque;
|
||||
typedef struct nativeTxCreationKeysOpaque LDKnativeTxCreationKeys;
|
||||
struct nativePreCalculatedTxCreationKeysOpaque;
|
||||
typedef struct nativePreCalculatedTxCreationKeysOpaque LDKnativePreCalculatedTxCreationKeys;
|
||||
struct nativeChannelPublicKeysOpaque;
|
||||
typedef struct nativeChannelPublicKeysOpaque LDKnativeChannelPublicKeys;
|
||||
struct nativeHTLCOutputInCommitmentOpaque;
|
||||
typedef struct nativeHTLCOutputInCommitmentOpaque LDKnativeHTLCOutputInCommitment;
|
||||
struct nativeLocalCommitmentTransactionOpaque;
|
||||
typedef struct nativeLocalCommitmentTransactionOpaque LDKnativeLocalCommitmentTransaction;
|
||||
struct nativeInitFeaturesOpaque;
|
||||
typedef struct nativeInitFeaturesOpaque LDKnativeInitFeatures;
|
||||
struct nativeNodeFeaturesOpaque;
|
||||
typedef struct nativeNodeFeaturesOpaque LDKnativeNodeFeatures;
|
||||
struct nativeChannelFeaturesOpaque;
|
||||
typedef struct nativeChannelFeaturesOpaque LDKnativeChannelFeatures;
|
||||
struct nativeRouteHopOpaque;
|
||||
typedef struct nativeRouteHopOpaque LDKnativeRouteHop;
|
||||
struct nativeRouteOpaque;
|
||||
typedef struct nativeRouteOpaque LDKnativeRoute;
|
||||
struct nativeRouteHintOpaque;
|
||||
typedef struct nativeRouteHintOpaque LDKnativeRouteHint;
|
||||
struct nativeNetworkGraphOpaque;
|
||||
typedef struct nativeNetworkGraphOpaque LDKnativeNetworkGraph;
|
||||
struct nativeLockedNetworkGraphOpaque;
|
||||
typedef struct nativeLockedNetworkGraphOpaque LDKnativeLockedNetworkGraph;
|
||||
struct nativeNetGraphMsgHandlerOpaque;
|
||||
typedef struct nativeNetGraphMsgHandlerOpaque LDKnativeNetGraphMsgHandler;
|
||||
struct nativeDirectionalChannelInfoOpaque;
|
||||
typedef struct nativeDirectionalChannelInfoOpaque LDKnativeDirectionalChannelInfo;
|
||||
struct nativeChannelInfoOpaque;
|
||||
typedef struct nativeChannelInfoOpaque LDKnativeChannelInfo;
|
||||
struct nativeRoutingFeesOpaque;
|
||||
typedef struct nativeRoutingFeesOpaque LDKnativeRoutingFees;
|
||||
struct nativeNodeAnnouncementInfoOpaque;
|
||||
typedef struct nativeNodeAnnouncementInfoOpaque LDKnativeNodeAnnouncementInfo;
|
||||
struct nativeNodeInfoOpaque;
|
||||
typedef struct nativeNodeInfoOpaque LDKnativeNodeInfo;
|
1
lightning-c-bindings/src/bitcoin/mod.rs
Normal file
1
lightning-c-bindings/src/bitcoin/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod network;
|
18
lightning-c-bindings/src/bitcoin/network.rs
Normal file
18
lightning-c-bindings/src/bitcoin/network.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use bitcoin::network::constants::Network as BitcoinNetwork;
|
||||
|
||||
#[repr(C)]
|
||||
pub enum Network {
|
||||
Bitcoin,
|
||||
Testnet,
|
||||
Regtest,
|
||||
}
|
||||
|
||||
impl Network {
|
||||
pub(crate) fn into_bitcoin(&self) -> BitcoinNetwork {
|
||||
match self {
|
||||
Network::Bitcoin => BitcoinNetwork::Bitcoin,
|
||||
Network::Testnet => BitcoinNetwork::Testnet,
|
||||
Network::Regtest => BitcoinNetwork::Regtest,
|
||||
}
|
||||
}
|
||||
}
|
405
lightning-c-bindings/src/c_types/derived.rs
Normal file
405
lightning-c-bindings/src/c_types/derived.rs
Normal file
|
@ -0,0 +1,405 @@
|
|||
#[no_mangle]
|
||||
pub type CVec_SpendableOutputDescriptorZ = crate::c_types::CVecTempl<crate::chain::keysinterface::SpendableOutputDescriptor>;
|
||||
#[no_mangle]
|
||||
pub static CVec_SpendableOutputDescriptorZ_free: extern "C" fn(CVec_SpendableOutputDescriptorZ) = crate::c_types::CVecTempl_free::<crate::chain::keysinterface::SpendableOutputDescriptor>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_MessageSendEventZ = crate::c_types::CVecTempl<crate::util::events::MessageSendEvent>;
|
||||
#[no_mangle]
|
||||
pub static CVec_MessageSendEventZ_free: extern "C" fn(CVec_MessageSendEventZ) = crate::c_types::CVecTempl_free::<crate::util::events::MessageSendEvent>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_EventZ = crate::c_types::CVecTempl<crate::util::events::Event>;
|
||||
#[no_mangle]
|
||||
pub static CVec_EventZ_free: extern "C" fn(CVec_EventZ) = crate::c_types::CVecTempl_free::<crate::util::events::Event>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type C2Tuple_Txidu32Z = crate::c_types::C2TupleTempl<crate::c_types::ThirtyTwoBytes, u32>;
|
||||
#[no_mangle]
|
||||
pub static C2Tuple_Txidu32Z_free: extern "C" fn(C2Tuple_Txidu32Z) = crate::c_types::C2TupleTempl_free::<crate::c_types::ThirtyTwoBytes, u32>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn C2Tuple_Txidu32Z_new(a: crate::c_types::ThirtyTwoBytes, b: u32) -> C2Tuple_Txidu32Z {
|
||||
C2Tuple_Txidu32Z {
|
||||
a: Box::into_raw(Box::new(a)),
|
||||
b: Box::into_raw(Box::new(b)),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type C2Tuple_Scriptu64Z = crate::c_types::C2TupleTempl<crate::c_types::derived::CVec_u8Z, u64>;
|
||||
#[no_mangle]
|
||||
pub static C2Tuple_Scriptu64Z_free: extern "C" fn(C2Tuple_Scriptu64Z) = crate::c_types::C2TupleTempl_free::<crate::c_types::derived::CVec_u8Z, u64>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn C2Tuple_Scriptu64Z_new(a: crate::c_types::derived::CVec_u8Z, b: u64) -> C2Tuple_Scriptu64Z {
|
||||
C2Tuple_Scriptu64Z {
|
||||
a: Box::into_raw(Box::new(a)),
|
||||
b: Box::into_raw(Box::new(b)),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_C2Tuple_Scriptu64ZChainErrorZ = crate::c_types::CResultTempl<crate::c_types::C2TupleTempl<crate::c_types::derived::CVec_u8Z, u64>, crate::chain::chaininterface::ChainError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_C2Tuple_Scriptu64ZChainErrorZ_free: extern "C" fn(CResult_C2Tuple_Scriptu64ZChainErrorZ) = crate::c_types::CResultTempl_free::<crate::c_types::C2TupleTempl<crate::c_types::derived::CVec_u8Z, u64>, crate::chain::chaininterface::ChainError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_C2Tuple_Scriptu64ZChainErrorZ_ok: extern "C" fn (C2Tuple_Scriptu64Z) -> CResult_C2Tuple_Scriptu64ZChainErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::C2TupleTempl<crate::c_types::derived::CVec_u8Z, u64>, crate::chain::chaininterface::ChainError>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_C2Tuple_Scriptu64ZChainErrorZ_err: extern "C" fn (crate::chain::chaininterface::ChainError) -> CResult_C2Tuple_Scriptu64ZChainErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::C2TupleTempl<crate::c_types::derived::CVec_u8Z, u64>, crate::chain::chaininterface::ChainError>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_usizeZ = crate::c_types::CVecTempl<usize>;
|
||||
#[no_mangle]
|
||||
pub static CVec_usizeZ_free: extern "C" fn(CVec_usizeZ) = crate::c_types::CVecTempl_free::<usize>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_TransactionZ = crate::c_types::CVecTempl<crate::c_types::derived::CVec_u8Z>;
|
||||
#[no_mangle]
|
||||
pub static CVec_TransactionZ_free: extern "C" fn(CVec_TransactionZ) = crate::c_types::CVecTempl_free::<crate::c_types::derived::CVec_u8Z>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type C2Tuple_u64u64Z = crate::c_types::C2TupleTempl<u64, u64>;
|
||||
#[no_mangle]
|
||||
pub static C2Tuple_u64u64Z_free: extern "C" fn(C2Tuple_u64u64Z) = crate::c_types::C2TupleTempl_free::<u64, u64>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn C2Tuple_u64u64Z_new(a: u64, b: u64) -> C2Tuple_u64u64Z {
|
||||
C2Tuple_u64u64Z {
|
||||
a: Box::into_raw(Box::new(a)),
|
||||
b: Box::into_raw(Box::new(b)),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_HTLCOutputInCommitmentZ = crate::c_types::CVecTempl<crate::ln::chan_utils::HTLCOutputInCommitment>;
|
||||
#[no_mangle]
|
||||
pub static CVec_HTLCOutputInCommitmentZ_free: extern "C" fn(CVec_HTLCOutputInCommitmentZ) = crate::c_types::CVecTempl_free::<crate::ln::chan_utils::HTLCOutputInCommitment>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_SignatureZ = crate::c_types::CVecTempl<crate::c_types::Signature>;
|
||||
#[no_mangle]
|
||||
pub static CVec_SignatureZ_free: extern "C" fn(CVec_SignatureZ) = crate::c_types::CVecTempl_free::<crate::c_types::Signature>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type C2Tuple_SignatureCVec_SignatureZZ = crate::c_types::C2TupleTempl<crate::c_types::Signature, crate::c_types::CVecTempl<crate::c_types::Signature>>;
|
||||
#[no_mangle]
|
||||
pub static C2Tuple_SignatureCVec_SignatureZZ_free: extern "C" fn(C2Tuple_SignatureCVec_SignatureZZ) = crate::c_types::C2TupleTempl_free::<crate::c_types::Signature, crate::c_types::CVecTempl<crate::c_types::Signature>>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn C2Tuple_SignatureCVec_SignatureZZ_new(a: crate::c_types::Signature, b: crate::c_types::derived::CVec_SignatureZ) -> C2Tuple_SignatureCVec_SignatureZZ {
|
||||
C2Tuple_SignatureCVec_SignatureZZ {
|
||||
a: Box::into_raw(Box::new(a)),
|
||||
b: Box::into_raw(Box::new(b)),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ = crate::c_types::CResultTempl<crate::c_types::C2TupleTempl<crate::c_types::Signature, crate::c_types::CVecTempl<crate::c_types::Signature>>, u8>;
|
||||
#[no_mangle]
|
||||
pub static CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_free: extern "C" fn(CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ) = crate::c_types::CResultTempl_free::<crate::c_types::C2TupleTempl<crate::c_types::Signature, crate::c_types::CVecTempl<crate::c_types::Signature>>, u8>;
|
||||
#[no_mangle]
|
||||
pub static CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_ok: extern "C" fn (C2Tuple_SignatureCVec_SignatureZZ) -> CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::C2TupleTempl<crate::c_types::Signature, crate::c_types::CVecTempl<crate::c_types::Signature>>, u8>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_err() -> CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ {
|
||||
crate::c_types::CResultTempl::err(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_SignatureNoneZ = crate::c_types::CResultTempl<crate::c_types::Signature, u8>;
|
||||
#[no_mangle]
|
||||
pub static CResult_SignatureNoneZ_free: extern "C" fn(CResult_SignatureNoneZ) = crate::c_types::CResultTempl_free::<crate::c_types::Signature, u8>;
|
||||
#[no_mangle]
|
||||
pub static CResult_SignatureNoneZ_ok: extern "C" fn (crate::c_types::Signature) -> CResult_SignatureNoneZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::Signature, u8>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn CResult_SignatureNoneZ_err() -> CResult_SignatureNoneZ {
|
||||
crate::c_types::CResultTempl::err(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_CVec_SignatureZNoneZ = crate::c_types::CResultTempl<crate::c_types::CVecTempl<crate::c_types::Signature>, u8>;
|
||||
#[no_mangle]
|
||||
pub static CResult_CVec_SignatureZNoneZ_free: extern "C" fn(CResult_CVec_SignatureZNoneZ) = crate::c_types::CResultTempl_free::<crate::c_types::CVecTempl<crate::c_types::Signature>, u8>;
|
||||
#[no_mangle]
|
||||
pub static CResult_CVec_SignatureZNoneZ_ok: extern "C" fn (CVec_SignatureZ) -> CResult_CVec_SignatureZNoneZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::CVecTempl<crate::c_types::Signature>, u8>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn CResult_CVec_SignatureZNoneZ_err() -> CResult_CVec_SignatureZNoneZ {
|
||||
crate::c_types::CResultTempl::err(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_NoneAPIErrorZ = crate::c_types::CResultTempl<u8, crate::util::errors::APIError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_NoneAPIErrorZ_free: extern "C" fn(CResult_NoneAPIErrorZ) = crate::c_types::CResultTempl_free::<u8, crate::util::errors::APIError>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn CResult_NoneAPIErrorZ_ok() -> CResult_NoneAPIErrorZ {
|
||||
crate::c_types::CResultTempl::ok(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_NoneAPIErrorZ_err: extern "C" fn (crate::util::errors::APIError) -> CResult_NoneAPIErrorZ =
|
||||
crate::c_types::CResultTempl::<u8, crate::util::errors::APIError>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_ChannelDetailsZ = crate::c_types::CVecTempl<crate::ln::channelmanager::ChannelDetails>;
|
||||
#[no_mangle]
|
||||
pub static CVec_ChannelDetailsZ_free: extern "C" fn(CVec_ChannelDetailsZ) = crate::c_types::CVecTempl_free::<crate::ln::channelmanager::ChannelDetails>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_NonePaymentSendFailureZ = crate::c_types::CResultTempl<u8, crate::ln::channelmanager::PaymentSendFailure>;
|
||||
#[no_mangle]
|
||||
pub static CResult_NonePaymentSendFailureZ_free: extern "C" fn(CResult_NonePaymentSendFailureZ) = crate::c_types::CResultTempl_free::<u8, crate::ln::channelmanager::PaymentSendFailure>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn CResult_NonePaymentSendFailureZ_ok() -> CResult_NonePaymentSendFailureZ {
|
||||
crate::c_types::CResultTempl::ok(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_NonePaymentSendFailureZ_err: extern "C" fn (crate::ln::channelmanager::PaymentSendFailure) -> CResult_NonePaymentSendFailureZ =
|
||||
crate::c_types::CResultTempl::<u8, crate::ln::channelmanager::PaymentSendFailure>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_NetAddressZ = crate::c_types::CVecTempl<crate::ln::msgs::NetAddress>;
|
||||
#[no_mangle]
|
||||
pub static CVec_NetAddressZ_free: extern "C" fn(CVec_NetAddressZ) = crate::c_types::CVecTempl_free::<crate::ln::msgs::NetAddress>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_ChannelMonitorZ = crate::c_types::CVecTempl<crate::ln::channelmonitor::ChannelMonitor>;
|
||||
#[no_mangle]
|
||||
pub static CVec_ChannelMonitorZ_free: extern "C" fn(CVec_ChannelMonitorZ) = crate::c_types::CVecTempl_free::<crate::ln::channelmonitor::ChannelMonitor>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_NoneChannelMonitorUpdateErrZ = crate::c_types::CResultTempl<u8, crate::ln::channelmonitor::ChannelMonitorUpdateErr>;
|
||||
#[no_mangle]
|
||||
pub static CResult_NoneChannelMonitorUpdateErrZ_free: extern "C" fn(CResult_NoneChannelMonitorUpdateErrZ) = crate::c_types::CResultTempl_free::<u8, crate::ln::channelmonitor::ChannelMonitorUpdateErr>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn CResult_NoneChannelMonitorUpdateErrZ_ok() -> CResult_NoneChannelMonitorUpdateErrZ {
|
||||
crate::c_types::CResultTempl::ok(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_NoneChannelMonitorUpdateErrZ_err: extern "C" fn (crate::ln::channelmonitor::ChannelMonitorUpdateErr) -> CResult_NoneChannelMonitorUpdateErrZ =
|
||||
crate::c_types::CResultTempl::<u8, crate::ln::channelmonitor::ChannelMonitorUpdateErr>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_MonitorEventZ = crate::c_types::CVecTempl<crate::ln::channelmonitor::MonitorEvent>;
|
||||
#[no_mangle]
|
||||
pub static CVec_MonitorEventZ_free: extern "C" fn(CVec_MonitorEventZ) = crate::c_types::CVecTempl_free::<crate::ln::channelmonitor::MonitorEvent>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_NoneMonitorUpdateErrorZ = crate::c_types::CResultTempl<u8, crate::ln::channelmonitor::MonitorUpdateError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_NoneMonitorUpdateErrorZ_free: extern "C" fn(CResult_NoneMonitorUpdateErrorZ) = crate::c_types::CResultTempl_free::<u8, crate::ln::channelmonitor::MonitorUpdateError>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn CResult_NoneMonitorUpdateErrorZ_ok() -> CResult_NoneMonitorUpdateErrorZ {
|
||||
crate::c_types::CResultTempl::ok(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_NoneMonitorUpdateErrorZ_err: extern "C" fn (crate::ln::channelmonitor::MonitorUpdateError) -> CResult_NoneMonitorUpdateErrorZ =
|
||||
crate::c_types::CResultTempl::<u8, crate::ln::channelmonitor::MonitorUpdateError>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type C2Tuple_OutPointScriptZ = crate::c_types::C2TupleTempl<crate::chain::transaction::OutPoint, crate::c_types::derived::CVec_u8Z>;
|
||||
#[no_mangle]
|
||||
pub static C2Tuple_OutPointScriptZ_free: extern "C" fn(C2Tuple_OutPointScriptZ) = crate::c_types::C2TupleTempl_free::<crate::chain::transaction::OutPoint, crate::c_types::derived::CVec_u8Z>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn C2Tuple_OutPointScriptZ_new(a: crate::chain::transaction::OutPoint, b: crate::c_types::derived::CVec_u8Z) -> C2Tuple_OutPointScriptZ {
|
||||
C2Tuple_OutPointScriptZ {
|
||||
a: Box::into_raw(Box::new(a)),
|
||||
b: Box::into_raw(Box::new(b)),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_UpdateAddHTLCZ = crate::c_types::CVecTempl<crate::ln::msgs::UpdateAddHTLC>;
|
||||
#[no_mangle]
|
||||
pub static CVec_UpdateAddHTLCZ_free: extern "C" fn(CVec_UpdateAddHTLCZ) = crate::c_types::CVecTempl_free::<crate::ln::msgs::UpdateAddHTLC>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_UpdateFulfillHTLCZ = crate::c_types::CVecTempl<crate::ln::msgs::UpdateFulfillHTLC>;
|
||||
#[no_mangle]
|
||||
pub static CVec_UpdateFulfillHTLCZ_free: extern "C" fn(CVec_UpdateFulfillHTLCZ) = crate::c_types::CVecTempl_free::<crate::ln::msgs::UpdateFulfillHTLC>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_UpdateFailHTLCZ = crate::c_types::CVecTempl<crate::ln::msgs::UpdateFailHTLC>;
|
||||
#[no_mangle]
|
||||
pub static CVec_UpdateFailHTLCZ_free: extern "C" fn(CVec_UpdateFailHTLCZ) = crate::c_types::CVecTempl_free::<crate::ln::msgs::UpdateFailHTLC>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_UpdateFailMalformedHTLCZ = crate::c_types::CVecTempl<crate::ln::msgs::UpdateFailMalformedHTLC>;
|
||||
#[no_mangle]
|
||||
pub static CVec_UpdateFailMalformedHTLCZ_free: extern "C" fn(CVec_UpdateFailMalformedHTLCZ) = crate::c_types::CVecTempl_free::<crate::ln::msgs::UpdateFailMalformedHTLC>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_boolLightningErrorZ = crate::c_types::CResultTempl<bool, crate::ln::msgs::LightningError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_boolLightningErrorZ_free: extern "C" fn(CResult_boolLightningErrorZ) = crate::c_types::CResultTempl_free::<bool, crate::ln::msgs::LightningError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_boolLightningErrorZ_ok: extern "C" fn (bool) -> CResult_boolLightningErrorZ =
|
||||
crate::c_types::CResultTempl::<bool, crate::ln::msgs::LightningError>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_boolLightningErrorZ_err: extern "C" fn (crate::ln::msgs::LightningError) -> CResult_boolLightningErrorZ =
|
||||
crate::c_types::CResultTempl::<bool, crate::ln::msgs::LightningError>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ = crate::c_types::C3TupleTempl<crate::ln::msgs::ChannelAnnouncement, crate::ln::msgs::ChannelUpdate, crate::ln::msgs::ChannelUpdate>;
|
||||
#[no_mangle]
|
||||
pub static C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free: extern "C" fn(C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ) = crate::c_types::C3TupleTempl_free::<crate::ln::msgs::ChannelAnnouncement, crate::ln::msgs::ChannelUpdate, crate::ln::msgs::ChannelUpdate>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_new(a: crate::ln::msgs::ChannelAnnouncement, b: crate::ln::msgs::ChannelUpdate, c: crate::ln::msgs::ChannelUpdate) -> C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ {
|
||||
C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ {
|
||||
a: Box::into_raw(Box::new(a)),
|
||||
b: Box::into_raw(Box::new(b)),
|
||||
c: Box::into_raw(Box::new(c)),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ = crate::c_types::CVecTempl<crate::c_types::C3TupleTempl<crate::ln::msgs::ChannelAnnouncement, crate::ln::msgs::ChannelUpdate, crate::ln::msgs::ChannelUpdate>>;
|
||||
#[no_mangle]
|
||||
pub static CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_free: extern "C" fn(CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ) = crate::c_types::CVecTempl_free::<crate::c_types::C3TupleTempl<crate::ln::msgs::ChannelAnnouncement, crate::ln::msgs::ChannelUpdate, crate::ln::msgs::ChannelUpdate>>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_NodeAnnouncementZ = crate::c_types::CVecTempl<crate::ln::msgs::NodeAnnouncement>;
|
||||
#[no_mangle]
|
||||
pub static CVec_NodeAnnouncementZ_free: extern "C" fn(CVec_NodeAnnouncementZ) = crate::c_types::CVecTempl_free::<crate::ln::msgs::NodeAnnouncement>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_PublicKeyZ = crate::c_types::CVecTempl<crate::c_types::PublicKey>;
|
||||
#[no_mangle]
|
||||
pub static CVec_PublicKeyZ_free: extern "C" fn(CVec_PublicKeyZ) = crate::c_types::CVecTempl_free::<crate::c_types::PublicKey>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_u8Z = crate::c_types::CVecTempl<u8>;
|
||||
#[no_mangle]
|
||||
pub static CVec_u8Z_free: extern "C" fn(CVec_u8Z) = crate::c_types::CVecTempl_free::<u8>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_CVec_u8ZPeerHandleErrorZ = crate::c_types::CResultTempl<crate::c_types::CVecTempl<u8>, crate::ln::peer_handler::PeerHandleError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_CVec_u8ZPeerHandleErrorZ_free: extern "C" fn(CResult_CVec_u8ZPeerHandleErrorZ) = crate::c_types::CResultTempl_free::<crate::c_types::CVecTempl<u8>, crate::ln::peer_handler::PeerHandleError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_CVec_u8ZPeerHandleErrorZ_ok: extern "C" fn (CVec_u8Z) -> CResult_CVec_u8ZPeerHandleErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::CVecTempl<u8>, crate::ln::peer_handler::PeerHandleError>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_CVec_u8ZPeerHandleErrorZ_err: extern "C" fn (crate::ln::peer_handler::PeerHandleError) -> CResult_CVec_u8ZPeerHandleErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::CVecTempl<u8>, crate::ln::peer_handler::PeerHandleError>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_NonePeerHandleErrorZ = crate::c_types::CResultTempl<u8, crate::ln::peer_handler::PeerHandleError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_NonePeerHandleErrorZ_free: extern "C" fn(CResult_NonePeerHandleErrorZ) = crate::c_types::CResultTempl_free::<u8, crate::ln::peer_handler::PeerHandleError>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn CResult_NonePeerHandleErrorZ_ok() -> CResult_NonePeerHandleErrorZ {
|
||||
crate::c_types::CResultTempl::ok(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_NonePeerHandleErrorZ_err: extern "C" fn (crate::ln::peer_handler::PeerHandleError) -> CResult_NonePeerHandleErrorZ =
|
||||
crate::c_types::CResultTempl::<u8, crate::ln::peer_handler::PeerHandleError>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_boolPeerHandleErrorZ = crate::c_types::CResultTempl<bool, crate::ln::peer_handler::PeerHandleError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_boolPeerHandleErrorZ_free: extern "C" fn(CResult_boolPeerHandleErrorZ) = crate::c_types::CResultTempl_free::<bool, crate::ln::peer_handler::PeerHandleError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_boolPeerHandleErrorZ_ok: extern "C" fn (bool) -> CResult_boolPeerHandleErrorZ =
|
||||
crate::c_types::CResultTempl::<bool, crate::ln::peer_handler::PeerHandleError>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_boolPeerHandleErrorZ_err: extern "C" fn (crate::ln::peer_handler::PeerHandleError) -> CResult_boolPeerHandleErrorZ =
|
||||
crate::c_types::CResultTempl::<bool, crate::ln::peer_handler::PeerHandleError>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_SecretKeySecpErrorZ = crate::c_types::CResultTempl<crate::c_types::SecretKey, crate::c_types::Secp256k1Error>;
|
||||
#[no_mangle]
|
||||
pub static CResult_SecretKeySecpErrorZ_free: extern "C" fn(CResult_SecretKeySecpErrorZ) = crate::c_types::CResultTempl_free::<crate::c_types::SecretKey, crate::c_types::Secp256k1Error>;
|
||||
#[no_mangle]
|
||||
pub static CResult_SecretKeySecpErrorZ_ok: extern "C" fn (crate::c_types::SecretKey) -> CResult_SecretKeySecpErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::SecretKey, crate::c_types::Secp256k1Error>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_SecretKeySecpErrorZ_err: extern "C" fn (crate::c_types::Secp256k1Error) -> CResult_SecretKeySecpErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::SecretKey, crate::c_types::Secp256k1Error>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_PublicKeySecpErrorZ = crate::c_types::CResultTempl<crate::c_types::PublicKey, crate::c_types::Secp256k1Error>;
|
||||
#[no_mangle]
|
||||
pub static CResult_PublicKeySecpErrorZ_free: extern "C" fn(CResult_PublicKeySecpErrorZ) = crate::c_types::CResultTempl_free::<crate::c_types::PublicKey, crate::c_types::Secp256k1Error>;
|
||||
#[no_mangle]
|
||||
pub static CResult_PublicKeySecpErrorZ_ok: extern "C" fn (crate::c_types::PublicKey) -> CResult_PublicKeySecpErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::PublicKey, crate::c_types::Secp256k1Error>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_PublicKeySecpErrorZ_err: extern "C" fn (crate::c_types::Secp256k1Error) -> CResult_PublicKeySecpErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::c_types::PublicKey, crate::c_types::Secp256k1Error>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_TxCreationKeysSecpErrorZ = crate::c_types::CResultTempl<crate::ln::chan_utils::TxCreationKeys, crate::c_types::Secp256k1Error>;
|
||||
#[no_mangle]
|
||||
pub static CResult_TxCreationKeysSecpErrorZ_free: extern "C" fn(CResult_TxCreationKeysSecpErrorZ) = crate::c_types::CResultTempl_free::<crate::ln::chan_utils::TxCreationKeys, crate::c_types::Secp256k1Error>;
|
||||
#[no_mangle]
|
||||
pub static CResult_TxCreationKeysSecpErrorZ_ok: extern "C" fn (crate::ln::chan_utils::TxCreationKeys) -> CResult_TxCreationKeysSecpErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::ln::chan_utils::TxCreationKeys, crate::c_types::Secp256k1Error>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_TxCreationKeysSecpErrorZ_err: extern "C" fn (crate::c_types::Secp256k1Error) -> CResult_TxCreationKeysSecpErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::ln::chan_utils::TxCreationKeys, crate::c_types::Secp256k1Error>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type C2Tuple_HTLCOutputInCommitmentSignatureZ = crate::c_types::C2TupleTempl<crate::ln::chan_utils::HTLCOutputInCommitment, crate::c_types::Signature>;
|
||||
#[no_mangle]
|
||||
pub static C2Tuple_HTLCOutputInCommitmentSignatureZ_free: extern "C" fn(C2Tuple_HTLCOutputInCommitmentSignatureZ) = crate::c_types::C2TupleTempl_free::<crate::ln::chan_utils::HTLCOutputInCommitment, crate::c_types::Signature>;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn C2Tuple_HTLCOutputInCommitmentSignatureZ_new(a: crate::ln::chan_utils::HTLCOutputInCommitment, b: crate::c_types::Signature) -> C2Tuple_HTLCOutputInCommitmentSignatureZ {
|
||||
C2Tuple_HTLCOutputInCommitmentSignatureZ {
|
||||
a: Box::into_raw(Box::new(a)),
|
||||
b: Box::into_raw(Box::new(b)),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_C2Tuple_HTLCOutputInCommitmentSignatureZZ = crate::c_types::CVecTempl<crate::c_types::C2TupleTempl<crate::ln::chan_utils::HTLCOutputInCommitment, crate::c_types::Signature>>;
|
||||
#[no_mangle]
|
||||
pub static CVec_C2Tuple_HTLCOutputInCommitmentSignatureZZ_free: extern "C" fn(CVec_C2Tuple_HTLCOutputInCommitmentSignatureZZ) = crate::c_types::CVecTempl_free::<crate::c_types::C2TupleTempl<crate::ln::chan_utils::HTLCOutputInCommitment, crate::c_types::Signature>>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_RouteHopZ = crate::c_types::CVecTempl<crate::routing::router::RouteHop>;
|
||||
#[no_mangle]
|
||||
pub static CVec_RouteHopZ_free: extern "C" fn(CVec_RouteHopZ) = crate::c_types::CVecTempl_free::<crate::routing::router::RouteHop>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_CVec_RouteHopZZ = crate::c_types::CVecTempl<crate::c_types::CVecTempl<crate::routing::router::RouteHop>>;
|
||||
#[no_mangle]
|
||||
pub static CVec_CVec_RouteHopZZ_free: extern "C" fn(CVec_CVec_RouteHopZZ) = crate::c_types::CVecTempl_free::<crate::c_types::CVecTempl<crate::routing::router::RouteHop>>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_RouteHintZ = crate::c_types::CVecTempl<crate::routing::router::RouteHint>;
|
||||
#[no_mangle]
|
||||
pub static CVec_RouteHintZ_free: extern "C" fn(CVec_RouteHintZ) = crate::c_types::CVecTempl_free::<crate::routing::router::RouteHint>;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CResult_RouteLightningErrorZ = crate::c_types::CResultTempl<crate::routing::router::Route, crate::ln::msgs::LightningError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_RouteLightningErrorZ_free: extern "C" fn(CResult_RouteLightningErrorZ) = crate::c_types::CResultTempl_free::<crate::routing::router::Route, crate::ln::msgs::LightningError>;
|
||||
#[no_mangle]
|
||||
pub static CResult_RouteLightningErrorZ_ok: extern "C" fn (crate::routing::router::Route) -> CResult_RouteLightningErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::routing::router::Route, crate::ln::msgs::LightningError>::ok;
|
||||
|
||||
#[no_mangle]
|
||||
pub static CResult_RouteLightningErrorZ_err: extern "C" fn (crate::ln::msgs::LightningError) -> CResult_RouteLightningErrorZ =
|
||||
crate::c_types::CResultTempl::<crate::routing::router::Route, crate::ln::msgs::LightningError>::err;
|
||||
|
||||
#[no_mangle]
|
||||
pub type CVec_u64Z = crate::c_types::CVecTempl<u64>;
|
||||
#[no_mangle]
|
||||
pub static CVec_u64Z_free: extern "C" fn(CVec_u64Z) = crate::c_types::CVecTempl_free::<u64>;
|
||||
|
419
lightning-c-bindings/src/c_types/mod.rs
Normal file
419
lightning-c-bindings/src/c_types/mod.rs
Normal file
|
@ -0,0 +1,419 @@
|
|||
pub mod derived;
|
||||
|
||||
use bitcoin::Script as BitcoinScript;
|
||||
use bitcoin::Transaction as BitcoinTransaction;
|
||||
use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;
|
||||
use bitcoin::secp256k1::key::SecretKey as SecpSecretKey;
|
||||
use bitcoin::secp256k1::Signature as SecpSignature;
|
||||
use bitcoin::secp256k1::Error as SecpError;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub struct PublicKey {
|
||||
pub compressed_form: [u8; 33],
|
||||
}
|
||||
impl PublicKey {
|
||||
pub(crate) fn from_rust(pk: &SecpPublicKey) -> Self {
|
||||
Self {
|
||||
compressed_form: pk.serialize(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn into_rust(&self) -> SecpPublicKey {
|
||||
SecpPublicKey::from_slice(&self.compressed_form).unwrap()
|
||||
}
|
||||
pub(crate) fn is_null(&self) -> bool { self.compressed_form[..] == [0; 33][..] }
|
||||
pub(crate) fn null() -> Self { Self { compressed_form: [0; 33] } }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SecretKey {
|
||||
pub bytes: [u8; 32],
|
||||
}
|
||||
impl SecretKey {
|
||||
// from_rust isn't implemented for a ref since we just return byte array refs directly
|
||||
pub(crate) fn from_rust(sk: SecpSecretKey) -> Self {
|
||||
let mut bytes = [0; 32];
|
||||
bytes.copy_from_slice(&sk[..]);
|
||||
Self { bytes }
|
||||
}
|
||||
pub(crate) fn into_rust(&self) -> SecpSecretKey {
|
||||
SecpSecretKey::from_slice(&self.bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Signature {
|
||||
pub compact_form: [u8; 64],
|
||||
}
|
||||
impl Signature {
|
||||
pub(crate) fn from_rust(pk: &SecpSignature) -> Self {
|
||||
Self {
|
||||
compact_form: pk.serialize_compact(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn into_rust(&self) -> SecpSignature {
|
||||
SecpSignature::from_compact(&self.compact_form).unwrap()
|
||||
}
|
||||
pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
|
||||
pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub enum Secp256k1Error {
|
||||
IncorrectSignature,
|
||||
InvalidMessage,
|
||||
InvalidPublicKey,
|
||||
InvalidSignature,
|
||||
InvalidSecretKey,
|
||||
InvalidRecoveryId,
|
||||
InvalidTweak,
|
||||
NotEnoughMemory,
|
||||
CallbackPanicked,
|
||||
}
|
||||
impl Secp256k1Error {
|
||||
pub(crate) fn from_rust(err: SecpError) -> Self {
|
||||
match err {
|
||||
SecpError::IncorrectSignature => Secp256k1Error::IncorrectSignature,
|
||||
SecpError::InvalidMessage => Secp256k1Error::InvalidMessage,
|
||||
SecpError::InvalidPublicKey => Secp256k1Error::InvalidPublicKey,
|
||||
SecpError::InvalidSignature => Secp256k1Error::InvalidSignature,
|
||||
SecpError::InvalidSecretKey => Secp256k1Error::InvalidSecretKey,
|
||||
SecpError::InvalidRecoveryId => Secp256k1Error::InvalidRecoveryId,
|
||||
SecpError::InvalidTweak => Secp256k1Error::InvalidTweak,
|
||||
SecpError::NotEnoughMemory => Secp256k1Error::NotEnoughMemory,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
/// A reference to a serialized transaction, in (pointer, length) form.
|
||||
/// This type does *not* own its own memory, so access to it after, eg, the call in which it was
|
||||
/// provided to you are invalid.
|
||||
pub struct Transaction {
|
||||
pub data: *const u8,
|
||||
pub datalen: usize,
|
||||
}
|
||||
impl Transaction {
|
||||
pub(crate) fn into_bitcoin(&self) -> BitcoinTransaction {
|
||||
if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); }
|
||||
::bitcoin::consensus::encode::deserialize(unsafe { std::slice::from_raw_parts(self.data, self.datalen) }).unwrap()
|
||||
}
|
||||
pub(crate) fn from_slice(s: &[u8]) -> Self {
|
||||
Self {
|
||||
data: s.as_ptr(),
|
||||
datalen: s.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone)]
|
||||
/// A transaction output including a scriptPubKey and value.
|
||||
/// This type *does* own its own memory, so must be free'd appropriately.
|
||||
pub struct TxOut {
|
||||
pub script_pubkey: derived::CVec_u8Z,
|
||||
pub value: u64,
|
||||
}
|
||||
|
||||
impl TxOut {
|
||||
pub(crate) fn into_rust(mut self) -> ::bitcoin::blockdata::transaction::TxOut {
|
||||
::bitcoin::blockdata::transaction::TxOut {
|
||||
script_pubkey: self.script_pubkey.into_rust().into(),
|
||||
value: self.value,
|
||||
}
|
||||
}
|
||||
pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
|
||||
Self {
|
||||
script_pubkey: CVecTempl::from(txout.script_pubkey.into_bytes()),
|
||||
value: txout.value
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxOut_free(_res: TxOut) { }
|
||||
|
||||
#[repr(C)]
|
||||
pub struct u8slice {
|
||||
pub data: *const u8,
|
||||
pub datalen: usize
|
||||
}
|
||||
impl u8slice {
|
||||
pub(crate) fn from_slice(s: &[u8]) -> Self {
|
||||
Self {
|
||||
data: s.as_ptr(),
|
||||
datalen: s.len(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn to_slice(&self) -> &[u8] {
|
||||
if self.datalen == 0 { return &[]; }
|
||||
unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct usizeslice {
|
||||
pub data: *const usize,
|
||||
pub datalen: usize
|
||||
}
|
||||
impl usizeslice {
|
||||
pub(crate) fn from_slice(s: &[usize]) -> Self {
|
||||
Self {
|
||||
data: s.as_ptr(),
|
||||
datalen: s.len(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn to_slice(&self) -> &[usize] {
|
||||
if self.datalen == 0 { return &[]; }
|
||||
unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
/// Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
|
||||
/// look up the corresponding function in rust-lightning's docs.
|
||||
pub struct ThirtyTwoBytes {
|
||||
pub data: [u8; 32],
|
||||
}
|
||||
impl ThirtyTwoBytes {
|
||||
pub(crate) fn null() -> Self {
|
||||
Self { data: [0; 32] }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ThreeBytes { pub data: [u8; 3], }
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub struct FourBytes { pub data: [u8; 4], }
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub struct TenBytes { pub data: [u8; 10], }
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub struct SixteenBytes { pub data: [u8; 16], }
|
||||
|
||||
pub(crate) struct VecWriter(pub Vec<u8>);
|
||||
impl lightning::util::ser::Writer for VecWriter {
|
||||
fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
|
||||
self.0.extend_from_slice(buf);
|
||||
Ok(())
|
||||
}
|
||||
fn size_hint(&mut self, size: usize) {
|
||||
self.0.reserve_exact(size);
|
||||
}
|
||||
}
|
||||
pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
|
||||
let mut out = VecWriter(Vec::new());
|
||||
i.write(&mut out).unwrap();
|
||||
CVecTempl::from(out.0)
|
||||
}
|
||||
pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
|
||||
I::read(&mut s.to_slice())
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
/// A Rust str object, ie a reference to a UTF8-valid string.
|
||||
/// This is *not* null-terminated so cannot be used directly as a C string!
|
||||
pub struct Str {
|
||||
pub chars: *const u8,
|
||||
pub len: usize
|
||||
}
|
||||
impl Into<Str> for &'static str {
|
||||
fn into(self) -> Str {
|
||||
Str { chars: self.as_ptr(), len: self.len() }
|
||||
}
|
||||
}
|
||||
impl Into<&'static str> for Str {
|
||||
fn into(self) -> &'static str {
|
||||
if self.len == 0 { return ""; }
|
||||
std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// Note that the C++ headers memset(0) all the Templ types to avoid deallocation!
|
||||
// Thus, they must gracefully handle being completely null in _free.
|
||||
|
||||
// TODO: Integer/bool primitives should avoid the pointer indirection for underlying types
|
||||
// everywhere in the containers.
|
||||
|
||||
#[repr(C)]
|
||||
pub union CResultPtr<O, E> {
|
||||
pub result: *mut O,
|
||||
pub err: *mut E,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct CResultTempl<O, E> {
|
||||
pub contents: CResultPtr<O, E>,
|
||||
pub result_ok: bool,
|
||||
}
|
||||
impl<O, E> CResultTempl<O, E> {
|
||||
pub(crate) extern "C" fn ok(o: O) -> Self {
|
||||
CResultTempl {
|
||||
contents: CResultPtr {
|
||||
result: Box::into_raw(Box::new(o)),
|
||||
},
|
||||
result_ok: true,
|
||||
}
|
||||
}
|
||||
pub(crate) extern "C" fn err(e: E) -> Self {
|
||||
CResultTempl {
|
||||
contents: CResultPtr {
|
||||
err: Box::into_raw(Box::new(e)),
|
||||
},
|
||||
result_ok: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub extern "C" fn CResultTempl_free<O, E>(_res: CResultTempl<O, E>) { }
|
||||
impl<O, E> Drop for CResultTempl<O, E> {
|
||||
fn drop(&mut self) {
|
||||
if self.result_ok {
|
||||
if unsafe { !self.contents.result.is_null() } {
|
||||
unsafe { Box::from_raw(self.contents.result) };
|
||||
}
|
||||
} else if unsafe { !self.contents.err.is_null() } {
|
||||
unsafe { Box::from_raw(self.contents.err) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CVecTempl<T> {
|
||||
pub data: *mut T,
|
||||
pub datalen: usize
|
||||
}
|
||||
impl<T> CVecTempl<T> {
|
||||
pub(crate) fn into_rust(&mut self) -> Vec<T> {
|
||||
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
|
||||
}
|
||||
pub(crate) fn as_slice(&self) -> &[T] {
|
||||
unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) }
|
||||
}
|
||||
}
|
||||
impl<T> From<Vec<T>> for CVecTempl<T> {
|
||||
fn from(v: Vec<T>) -> Self {
|
||||
let datalen = v.len();
|
||||
let data = Box::into_raw(v.into_boxed_slice());
|
||||
CVecTempl { datalen, data: unsafe { (*data).as_mut_ptr() } }
|
||||
}
|
||||
}
|
||||
pub extern "C" fn CVecTempl_free<T>(_res: CVecTempl<T>) { }
|
||||
impl<T> Drop for CVecTempl<T> {
|
||||
fn drop(&mut self) {
|
||||
if self.datalen == 0 { return; }
|
||||
unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) };
|
||||
}
|
||||
}
|
||||
impl<T: Clone> Clone for CVecTempl<T> {
|
||||
fn clone(&self) -> Self {
|
||||
let mut res = Vec::new();
|
||||
if self.datalen == 0 { return Self::from(res); }
|
||||
res.clone_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) });
|
||||
Self::from(res)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct C2TupleTempl<A, B> {
|
||||
pub a: *mut A,
|
||||
pub b: *mut B,
|
||||
}
|
||||
impl<A, B> From<(A, B)> for C2TupleTempl<A, B> {
|
||||
fn from(tup: (A, B)) -> Self {
|
||||
Self {
|
||||
a: Box::into_raw(Box::new(tup.0)),
|
||||
b: Box::into_raw(Box::new(tup.1)),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<A, B> C2TupleTempl<A, B> {
|
||||
pub(crate) fn to_rust(mut self) -> (A, B) {
|
||||
let res = (unsafe { *Box::from_raw(self.a) }, unsafe { *Box::from_raw(self.b) });
|
||||
self.a = std::ptr::null_mut();
|
||||
self.b = std::ptr::null_mut();
|
||||
res
|
||||
}
|
||||
}
|
||||
pub extern "C" fn C2TupleTempl_free<A, B>(_res: C2TupleTempl<A, B>) { }
|
||||
impl<A, B> Drop for C2TupleTempl<A, B> {
|
||||
fn drop(&mut self) {
|
||||
if !self.a.is_null() {
|
||||
unsafe { Box::from_raw(self.a) };
|
||||
}
|
||||
if !self.b.is_null() {
|
||||
unsafe { Box::from_raw(self.b) };
|
||||
}
|
||||
}
|
||||
}
|
||||
impl <A: Clone, B: Clone> Clone for C2TupleTempl<A, B> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
a: Box::into_raw(Box::new(unsafe { &*self.a }.clone())),
|
||||
b: Box::into_raw(Box::new(unsafe { &*self.b }.clone()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct C3TupleTempl<A, B, C> {
|
||||
pub a: *mut A,
|
||||
pub b: *mut B,
|
||||
pub c: *mut C,
|
||||
}
|
||||
impl<A, B, C> From<(A, B, C)> for C3TupleTempl<A, B, C> {
|
||||
fn from(tup: (A, B, C)) -> Self {
|
||||
Self {
|
||||
a: Box::into_raw(Box::new(tup.0)),
|
||||
b: Box::into_raw(Box::new(tup.1)),
|
||||
c: Box::into_raw(Box::new(tup.2)),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<A, B, C> C3TupleTempl<A, B, C> {
|
||||
pub(crate) fn to_rust(mut self) -> (A, B, C) {
|
||||
let res = (unsafe { *Box::from_raw(self.a) }, unsafe { *Box::from_raw(self.b) }, unsafe { *Box::from_raw(self.c) });
|
||||
self.a = std::ptr::null_mut();
|
||||
self.b = std::ptr::null_mut();
|
||||
self.c = std::ptr::null_mut();
|
||||
res
|
||||
}
|
||||
}
|
||||
pub extern "C" fn C3TupleTempl_free<A, B, C>(_res: C3TupleTempl<A, B, C>) { }
|
||||
impl<A, B, C> Drop for C3TupleTempl<A, B, C> {
|
||||
fn drop(&mut self) {
|
||||
if !self.a.is_null() {
|
||||
unsafe { Box::from_raw(self.a) };
|
||||
}
|
||||
if !self.b.is_null() {
|
||||
unsafe { Box::from_raw(self.b) };
|
||||
}
|
||||
if !self.c.is_null() {
|
||||
unsafe { Box::from_raw(self.c) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Utility to make it easy to set a pointer to null and get its original value in line.
|
||||
pub(crate) trait TakePointer<T> {
|
||||
fn take_ptr(&mut self) -> T;
|
||||
}
|
||||
impl<T> TakePointer<*const T> for *const T {
|
||||
fn take_ptr(&mut self) -> *const T {
|
||||
let ret = *self;
|
||||
*self = std::ptr::null();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl<T> TakePointer<*mut T> for *mut T {
|
||||
fn take_ptr(&mut self) -> *mut T {
|
||||
let ret = *self;
|
||||
*self = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
606
lightning-c-bindings/src/chain/chaininterface.rs
Normal file
606
lightning-c-bindings/src/chain/chaininterface.rs
Normal file
|
@ -0,0 +1,606 @@
|
|||
//! Traits and utility impls which allow other parts of rust-lightning to interact with the
|
||||
//! blockchain.
|
||||
//!
|
||||
//! Includes traits for monitoring and receiving notifications of new blocks and block
|
||||
//! disconnections, transaction broadcasting, and feerate information requests.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
/// Used to give chain error details upstream
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub enum ChainError {
|
||||
/// Client doesn't support UTXO lookup (but the chain hash matches our genesis block hash)
|
||||
NotSupported,
|
||||
/// Chain isn't the one watched
|
||||
NotWatched,
|
||||
/// Tx doesn't exist or is unconfirmed
|
||||
UnknownTx,
|
||||
}
|
||||
use lightning::chain::chaininterface::ChainError as nativeChainError;
|
||||
impl ChainError {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn to_native(&self) -> nativeChainError {
|
||||
match self {
|
||||
ChainError::NotSupported => nativeChainError::NotSupported,
|
||||
ChainError::NotWatched => nativeChainError::NotWatched,
|
||||
ChainError::UnknownTx => nativeChainError::UnknownTx,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn into_native(self) -> nativeChainError {
|
||||
match self {
|
||||
ChainError::NotSupported => nativeChainError::NotSupported,
|
||||
ChainError::NotWatched => nativeChainError::NotWatched,
|
||||
ChainError::UnknownTx => nativeChainError::UnknownTx,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn from_native(native: &nativeChainError) -> Self {
|
||||
match native {
|
||||
nativeChainError::NotSupported => ChainError::NotSupported,
|
||||
nativeChainError::NotWatched => ChainError::NotWatched,
|
||||
nativeChainError::UnknownTx => ChainError::UnknownTx,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn native_into(native: nativeChainError) -> Self {
|
||||
match native {
|
||||
nativeChainError::NotSupported => ChainError::NotSupported,
|
||||
nativeChainError::NotWatched => ChainError::NotWatched,
|
||||
nativeChainError::UnknownTx => ChainError::UnknownTx,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// An interface to request notification of certain scripts as they appear the
|
||||
/// chain.
|
||||
///
|
||||
/// Note that all of the functions implemented here *must* be reentrant-safe (obviously - they're
|
||||
/// called from inside the library in response to ChainListener events, P2P events, or timer
|
||||
/// events).
|
||||
#[repr(C)]
|
||||
pub struct ChainWatchInterface {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Provides a txid/random-scriptPubKey-in-the-tx which much be watched for.
|
||||
pub install_watch_tx: extern "C" fn (this_arg: *const c_void, txid: *const [u8; 32], script_pub_key: crate::c_types::u8slice),
|
||||
/// Provides an outpoint which must be watched for, providing any transactions which spend the
|
||||
/// given outpoint.
|
||||
pub install_watch_outpoint: extern "C" fn (this_arg: *const c_void, outpoint: crate::c_types::derived::C2Tuple_Txidu32Z, out_script: crate::c_types::u8slice),
|
||||
/// Indicates that a listener needs to see all transactions.
|
||||
pub watch_all_txn: extern "C" fn (this_arg: *const c_void),
|
||||
/// Gets the script and value in satoshis for a given unspent transaction output given a
|
||||
/// short_channel_id (aka unspent_tx_output_identier). For BTC/tBTC channels the top three
|
||||
/// bytes are the block height, the next 3 the transaction index within the block, and the
|
||||
/// final two the output within the transaction.
|
||||
#[must_use]
|
||||
pub get_chain_utxo: extern "C" fn (this_arg: *const c_void, genesis_hash: crate::c_types::ThirtyTwoBytes, unspent_tx_output_identifier: u64) -> crate::c_types::derived::CResult_C2Tuple_Scriptu64ZChainErrorZ,
|
||||
/// Gets the list of transaction indices within a given block that the ChainWatchInterface is
|
||||
/// watching for.
|
||||
#[must_use]
|
||||
pub filter_block: extern "C" fn (this_arg: *const c_void, block: crate::c_types::u8slice) -> crate::c_types::derived::CVec_usizeZ,
|
||||
/// Returns a usize that changes when the ChainWatchInterface's watched data is modified.
|
||||
/// Users of `filter_block` should pre-save a copy of `reentered`'s return value and use it to
|
||||
/// determine whether they need to re-filter a given block.
|
||||
#[must_use]
|
||||
pub reentered: extern "C" fn (this_arg: *const c_void) -> usize,
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
unsafe impl Sync for ChainWatchInterface {}
|
||||
unsafe impl Send for ChainWatchInterface {}
|
||||
|
||||
use lightning::chain::chaininterface::ChainWatchInterface as rustChainWatchInterface;
|
||||
impl rustChainWatchInterface for ChainWatchInterface {
|
||||
fn install_watch_tx(&self, txid: &bitcoin::hash_types::Txid, script_pub_key: &bitcoin::blockdata::script::Script) {
|
||||
(self.install_watch_tx)(self.this_arg, txid.as_inner(), crate::c_types::u8slice::from_slice(&script_pub_key[..]))
|
||||
}
|
||||
fn install_watch_outpoint(&self, outpoint: (bitcoin::hash_types::Txid, u32), out_script: &bitcoin::blockdata::script::Script) {
|
||||
let (mut orig_outpoint_0, mut orig_outpoint_1) = outpoint; let mut local_outpoint = (crate::c_types::ThirtyTwoBytes { data: orig_outpoint_0.into_inner() }, orig_outpoint_1).into();
|
||||
(self.install_watch_outpoint)(self.this_arg, local_outpoint, crate::c_types::u8slice::from_slice(&out_script[..]))
|
||||
}
|
||||
fn watch_all_txn(&self) {
|
||||
(self.watch_all_txn)(self.this_arg)
|
||||
}
|
||||
fn get_chain_utxo(&self, genesis_hash: bitcoin::hash_types::BlockHash, unspent_tx_output_identifier: u64) -> Result<(bitcoin::blockdata::script::Script, u64), lightning::chain::chaininterface::ChainError> {
|
||||
let mut ret = (self.get_chain_utxo)(self.this_arg, crate::c_types::ThirtyTwoBytes { data: genesis_hash.into_inner() }, unspent_tx_output_identifier);
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (*unsafe { Box::from_raw(ret.contents.result.take_ptr()) }).to_rust(); let mut local_ret_0 = (::bitcoin::blockdata::script::Script::from(orig_ret_0_0.into_rust()), orig_ret_0_1); local_ret_0 }), false => Err( { (*unsafe { Box::from_raw(ret.contents.err.take_ptr()) }).into_native() })};
|
||||
local_ret
|
||||
}
|
||||
fn filter_block(&self, block: &bitcoin::blockdata::block::Block) -> Vec<usize> {
|
||||
let mut local_block = ::bitcoin::consensus::encode::serialize(block);
|
||||
let mut ret = (self.filter_block)(self.this_arg, crate::c_types::u8slice::from_slice(&local_block));
|
||||
let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { item }); };
|
||||
local_ret
|
||||
}
|
||||
fn reentered(&self) -> usize {
|
||||
let mut ret = (self.reentered)(self.this_arg);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for ChainWatchInterface {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchInterface_free(this_ptr: ChainWatchInterface) { }
|
||||
impl Drop for ChainWatchInterface {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// An interface to send a transaction to the Bitcoin network.
|
||||
#[repr(C)]
|
||||
pub struct BroadcasterInterface {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Sends a transaction out to (hopefully) be mined.
|
||||
pub broadcast_transaction: extern "C" fn (this_arg: *const c_void, tx: crate::c_types::Transaction),
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
unsafe impl Sync for BroadcasterInterface {}
|
||||
unsafe impl Send for BroadcasterInterface {}
|
||||
|
||||
use lightning::chain::chaininterface::BroadcasterInterface as rustBroadcasterInterface;
|
||||
impl rustBroadcasterInterface for BroadcasterInterface {
|
||||
fn broadcast_transaction(&self, tx: &bitcoin::blockdata::transaction::Transaction) {
|
||||
let mut local_tx = ::bitcoin::consensus::encode::serialize(tx);
|
||||
(self.broadcast_transaction)(self.this_arg, crate::c_types::Transaction::from_slice(&local_tx))
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for BroadcasterInterface {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn BroadcasterInterface_free(this_ptr: BroadcasterInterface) { }
|
||||
impl Drop for BroadcasterInterface {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// A trait indicating a desire to listen for events from the chain
|
||||
#[repr(C)]
|
||||
pub struct ChainListener {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Notifies a listener that a block was connected.
|
||||
///
|
||||
/// The txn_matched array should be set to references to transactions which matched the
|
||||
/// relevant installed watch outpoints/txn, or the full set of transactions in the block.
|
||||
///
|
||||
/// Note that if txn_matched includes only matched transactions, and a new
|
||||
/// transaction/outpoint is watched during a block_connected call, the block *must* be
|
||||
/// re-scanned with the new transaction/outpoints and block_connected should be called
|
||||
/// again with the same header and (at least) the new transactions.
|
||||
///
|
||||
/// Note that if non-new transaction/outpoints are be registered during a call, a second call
|
||||
/// *must not* happen.
|
||||
///
|
||||
/// This also means those counting confirmations using block_connected callbacks should watch
|
||||
/// for duplicate headers and not count them towards confirmations!
|
||||
pub block_connected: extern "C" fn (this_arg: *const c_void, header: *const [u8; 80], height: u32, txn_matched: crate::c_types::derived::CVec_TransactionZ, indexes_of_txn_matched: crate::c_types::usizeslice),
|
||||
/// Notifies a listener that a block was disconnected.
|
||||
/// Unlike block_connected, this *must* never be called twice for the same disconnect event.
|
||||
/// Height must be the one of the block which was disconnected (not new height of the best chain)
|
||||
pub block_disconnected: extern "C" fn (this_arg: *const c_void, header: *const [u8; 80], disconnected_height: u32),
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
unsafe impl Sync for ChainListener {}
|
||||
unsafe impl Send for ChainListener {}
|
||||
|
||||
use lightning::chain::chaininterface::ChainListener as rustChainListener;
|
||||
impl rustChainListener for ChainListener {
|
||||
fn block_connected(&self, header: &bitcoin::blockdata::block::BlockHeader, height: u32, txn_matched: &[&bitcoin::blockdata::transaction::Transaction], indexes_of_txn_matched: &[usize]) {
|
||||
let mut local_header = { let mut s = [0u8; 80]; s[..].copy_from_slice(&::bitcoin::consensus::encode::serialize(header)); s };
|
||||
let mut local_txn_matched = Vec::new(); for item in txn_matched.iter() { local_txn_matched.push( { let mut local_txn_matched_0 = ::bitcoin::consensus::encode::serialize(&**item); local_txn_matched_0.into() }); };
|
||||
let mut local_indexes_of_txn_matched = crate::c_types::usizeslice::from_slice(indexes_of_txn_matched);
|
||||
(self.block_connected)(self.this_arg, &local_header, height, local_txn_matched.into(), local_indexes_of_txn_matched)
|
||||
}
|
||||
fn block_disconnected(&self, header: &bitcoin::blockdata::block::BlockHeader, disconnected_height: u32) {
|
||||
let mut local_header = { let mut s = [0u8; 80]; s[..].copy_from_slice(&::bitcoin::consensus::encode::serialize(header)); s };
|
||||
(self.block_disconnected)(self.this_arg, &local_header, disconnected_height)
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for ChainListener {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainListener_free(this_ptr: ChainListener) { }
|
||||
impl Drop for ChainListener {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// An enum that represents the speed at which we want a transaction to confirm used for feerate
|
||||
/// estimation.
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub enum ConfirmationTarget {
|
||||
/// We are happy with this transaction confirming slowly when feerate drops some.
|
||||
Background,
|
||||
/// We'd like this transaction to confirm without major delay, but 12-18 blocks is fine.
|
||||
Normal,
|
||||
/// We'd like this transaction to confirm in the next few blocks.
|
||||
HighPriority,
|
||||
}
|
||||
use lightning::chain::chaininterface::ConfirmationTarget as nativeConfirmationTarget;
|
||||
impl ConfirmationTarget {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn to_native(&self) -> nativeConfirmationTarget {
|
||||
match self {
|
||||
ConfirmationTarget::Background => nativeConfirmationTarget::Background,
|
||||
ConfirmationTarget::Normal => nativeConfirmationTarget::Normal,
|
||||
ConfirmationTarget::HighPriority => nativeConfirmationTarget::HighPriority,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn into_native(self) -> nativeConfirmationTarget {
|
||||
match self {
|
||||
ConfirmationTarget::Background => nativeConfirmationTarget::Background,
|
||||
ConfirmationTarget::Normal => nativeConfirmationTarget::Normal,
|
||||
ConfirmationTarget::HighPriority => nativeConfirmationTarget::HighPriority,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn from_native(native: &nativeConfirmationTarget) -> Self {
|
||||
match native {
|
||||
nativeConfirmationTarget::Background => ConfirmationTarget::Background,
|
||||
nativeConfirmationTarget::Normal => ConfirmationTarget::Normal,
|
||||
nativeConfirmationTarget::HighPriority => ConfirmationTarget::HighPriority,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn native_into(native: nativeConfirmationTarget) -> Self {
|
||||
match native {
|
||||
nativeConfirmationTarget::Background => ConfirmationTarget::Background,
|
||||
nativeConfirmationTarget::Normal => ConfirmationTarget::Normal,
|
||||
nativeConfirmationTarget::HighPriority => ConfirmationTarget::HighPriority,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// A trait which should be implemented to provide feerate information on a number of time
|
||||
/// horizons.
|
||||
///
|
||||
/// Note that all of the functions implemented here *must* be reentrant-safe (obviously - they're
|
||||
/// called from inside the library in response to ChainListener events, P2P events, or timer
|
||||
/// events).
|
||||
#[repr(C)]
|
||||
pub struct FeeEstimator {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Gets estimated satoshis of fee required per 1000 Weight-Units.
|
||||
///
|
||||
/// Must be no smaller than 253 (ie 1 satoshi-per-byte rounded up to ensure later round-downs
|
||||
/// don't put us below 1 satoshi-per-byte).
|
||||
///
|
||||
/// This translates to:
|
||||
/// * satoshis-per-byte * 250
|
||||
/// * ceil(satoshis-per-kbyte / 4)
|
||||
#[must_use]
|
||||
pub get_est_sat_per_1000_weight: extern "C" fn (this_arg: *const c_void, confirmation_target: crate::chain::chaininterface::ConfirmationTarget) -> u32,
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
unsafe impl Sync for FeeEstimator {}
|
||||
unsafe impl Send for FeeEstimator {}
|
||||
|
||||
use lightning::chain::chaininterface::FeeEstimator as rustFeeEstimator;
|
||||
impl rustFeeEstimator for FeeEstimator {
|
||||
fn get_est_sat_per_1000_weight(&self, confirmation_target: lightning::chain::chaininterface::ConfirmationTarget) -> u32 {
|
||||
let mut ret = (self.get_est_sat_per_1000_weight)(self.this_arg, crate::chain::chaininterface::ConfirmationTarget::native_into(confirmation_target));
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for FeeEstimator {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn FeeEstimator_free(this_ptr: FeeEstimator) { }
|
||||
impl Drop for FeeEstimator {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub static MIN_RELAY_FEE_SAT_PER_1000_WEIGHT: u64 = lightning::chain::chaininterface::MIN_RELAY_FEE_SAT_PER_1000_WEIGHT;
|
||||
|
||||
use lightning::chain::chaininterface::ChainWatchedUtil as nativeChainWatchedUtilImport;
|
||||
type nativeChainWatchedUtil = nativeChainWatchedUtilImport;
|
||||
|
||||
/// Utility for tracking registered txn/outpoints and checking for matches
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChainWatchedUtil {
|
||||
/// Nearly everyhwere, 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 nativeChainWatchedUtil,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChainWatchedUtil {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchedUtil_free(this_ptr: ChainWatchedUtil) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChainWatchedUtil_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChainWatchedUtil); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChainWatchedUtil {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChainWatchedUtil {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Constructs an empty (watches nothing) ChainWatchedUtil
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchedUtil_new() -> ChainWatchedUtil {
|
||||
let mut ret = lightning::chain::chaininterface::ChainWatchedUtil::new();
|
||||
ChainWatchedUtil { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Registers a tx for monitoring, returning true if it was a new tx and false if we'd already
|
||||
/// been watching for it.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchedUtil_register_tx(this_arg: &mut ChainWatchedUtil, txid: *const [u8; 32], script_pub_key: crate::c_types::u8slice) -> bool {
|
||||
let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChainWatchedUtil)) }.register_tx(&::bitcoin::hash_types::Txid::from_slice(&unsafe { &*txid }[..]).unwrap(), &::bitcoin::blockdata::script::Script::from(Vec::from(script_pub_key.to_slice())));
|
||||
ret
|
||||
}
|
||||
|
||||
/// Registers an outpoint for monitoring, returning true if it was a new outpoint and false if
|
||||
/// we'd already been watching for it
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchedUtil_register_outpoint(this_arg: &mut ChainWatchedUtil, mut outpoint: crate::c_types::derived::C2Tuple_Txidu32Z, _script_pub_key: crate::c_types::u8slice) -> bool {
|
||||
let (mut orig_outpoint_0, mut orig_outpoint_1) = outpoint.to_rust(); let mut local_outpoint = (::bitcoin::hash_types::Txid::from_slice(&orig_outpoint_0.data[..]).unwrap(), orig_outpoint_1);
|
||||
let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChainWatchedUtil)) }.register_outpoint(local_outpoint, &::bitcoin::blockdata::script::Script::from(Vec::from(_script_pub_key.to_slice())));
|
||||
ret
|
||||
}
|
||||
|
||||
/// Sets us to match all transactions, returning true if this is a new setting and false if
|
||||
/// we'd already been set to match everything.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchedUtil_watch_all(this_arg: &mut ChainWatchedUtil) -> bool {
|
||||
let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChainWatchedUtil)) }.watch_all();
|
||||
ret
|
||||
}
|
||||
|
||||
/// Checks if a given transaction matches the current filter.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchedUtil_does_match_tx(this_arg: &ChainWatchedUtil, tx: crate::c_types::Transaction) -> bool {
|
||||
let mut ret = unsafe { &*this_arg.inner }.does_match_tx(&tx.into_bitcoin());
|
||||
ret
|
||||
}
|
||||
|
||||
|
||||
use lightning::chain::chaininterface::BlockNotifier as nativeBlockNotifierImport;
|
||||
type nativeBlockNotifier = nativeBlockNotifierImport<'static, crate::chain::chaininterface::ChainListener, crate::chain::chaininterface::ChainWatchInterface>;
|
||||
|
||||
/// Utility for notifying listeners about new blocks, and handling block rescans if new watch
|
||||
/// data is registered.
|
||||
///
|
||||
/// Rather than using a plain BlockNotifier, it is preferable to use either a BlockNotifierArc
|
||||
/// or a BlockNotifierRef for conciseness. See their documentation for more details, but essentially
|
||||
/// you should default to using a BlockNotifierRef, and use a BlockNotifierArc instead when you
|
||||
/// require ChainListeners with static lifetimes, such as when you're using lightning-net-tokio.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct BlockNotifier {
|
||||
/// Nearly everyhwere, 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 nativeBlockNotifier,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for BlockNotifier {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn BlockNotifier_free(this_ptr: BlockNotifier) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn BlockNotifier_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeBlockNotifier); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl BlockNotifier {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeBlockNotifier {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Constructs a new BlockNotifier without any listeners.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn BlockNotifier_new(mut chain_monitor: crate::chain::chaininterface::ChainWatchInterface) -> crate::chain::chaininterface::BlockNotifier {
|
||||
let mut ret = lightning::chain::chaininterface::BlockNotifier::new(chain_monitor);
|
||||
crate::chain::chaininterface::BlockNotifier { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Register the given listener to receive events.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn BlockNotifier_register_listener(this_arg: &BlockNotifier, mut listener: crate::chain::chaininterface::ChainListener) {
|
||||
unsafe { &*this_arg.inner }.register_listener(listener)
|
||||
}
|
||||
|
||||
/// Notify listeners that a block was connected given a full, unfiltered block.
|
||||
///
|
||||
/// Handles re-scanning the block and calling block_connected again if listeners register new
|
||||
/// watch data during the callbacks for you (see ChainListener::block_connected for more info).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn BlockNotifier_block_connected(this_arg: &BlockNotifier, block: crate::c_types::u8slice, mut height: u32) {
|
||||
unsafe { &*this_arg.inner }.block_connected(&::bitcoin::consensus::encode::deserialize(block.to_slice()).unwrap(), height)
|
||||
}
|
||||
|
||||
/// Notify listeners that a block was connected, given pre-filtered list of transactions in the
|
||||
/// block which matched the filter (probably using does_match_tx).
|
||||
///
|
||||
/// Returns true if notified listeners registered additional watch data (implying that the
|
||||
/// block must be re-scanned and this function called again prior to further block_connected
|
||||
/// calls, see ChainListener::block_connected for more info).
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn BlockNotifier_block_connected_checked(this_arg: &BlockNotifier, header: *const [u8; 80], mut height: u32, mut txn_matched: crate::c_types::derived::CVec_TransactionZ, mut indexes_of_txn_matched: crate::c_types::usizeslice) -> bool {
|
||||
let mut local_txn_matched = Vec::new(); for mut item in txn_matched.into_rust().drain(..) { local_txn_matched.push( { ::bitcoin::consensus::encode::deserialize(&item.into_rust()[..]).unwrap() }); };
|
||||
let mut ret = unsafe { &*this_arg.inner }.block_connected_checked(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), height, &local_txn_matched.iter().collect::<Vec<_>>()[..], indexes_of_txn_matched.to_slice());
|
||||
ret
|
||||
}
|
||||
|
||||
/// Notify listeners that a block was disconnected.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn BlockNotifier_block_disconnected(this_arg: &BlockNotifier, header: *const [u8; 80], mut disconnected_height: u32) {
|
||||
unsafe { &*this_arg.inner }.block_disconnected(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), disconnected_height)
|
||||
}
|
||||
|
||||
|
||||
use lightning::chain::chaininterface::ChainWatchInterfaceUtil as nativeChainWatchInterfaceUtilImport;
|
||||
type nativeChainWatchInterfaceUtil = nativeChainWatchInterfaceUtilImport;
|
||||
|
||||
/// Utility to capture some common parts of ChainWatchInterface implementors.
|
||||
///
|
||||
/// Keeping a local copy of this in a ChainWatchInterface implementor is likely useful.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChainWatchInterfaceUtil {
|
||||
/// Nearly everyhwere, 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 nativeChainWatchInterfaceUtil,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChainWatchInterfaceUtil {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchInterfaceUtil_free(this_ptr: ChainWatchInterfaceUtil) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChainWatchInterfaceUtil_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChainWatchInterfaceUtil); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChainWatchInterfaceUtil {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChainWatchInterfaceUtil {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchInterfaceUtil_as_ChainWatchInterface(this_arg: *const ChainWatchInterfaceUtil) -> crate::chain::chaininterface::ChainWatchInterface {
|
||||
crate::chain::chaininterface::ChainWatchInterface {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
install_watch_tx: ChainWatchInterfaceUtil_ChainWatchInterface_install_watch_tx,
|
||||
install_watch_outpoint: ChainWatchInterfaceUtil_ChainWatchInterface_install_watch_outpoint,
|
||||
watch_all_txn: ChainWatchInterfaceUtil_ChainWatchInterface_watch_all_txn,
|
||||
get_chain_utxo: ChainWatchInterfaceUtil_ChainWatchInterface_get_chain_utxo,
|
||||
filter_block: ChainWatchInterfaceUtil_ChainWatchInterface_filter_block,
|
||||
reentered: ChainWatchInterfaceUtil_ChainWatchInterface_reentered,
|
||||
}
|
||||
}
|
||||
use lightning::chain::chaininterface::ChainWatchInterface as ChainWatchInterfaceTraitImport;
|
||||
extern "C" fn ChainWatchInterfaceUtil_ChainWatchInterface_install_watch_tx(this_arg: *const c_void, txid: *const [u8; 32], script_pub_key: crate::c_types::u8slice) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChainWatchInterfaceUtil) }.install_watch_tx(&::bitcoin::hash_types::Txid::from_slice(&unsafe { &*txid }[..]).unwrap(), &::bitcoin::blockdata::script::Script::from(Vec::from(script_pub_key.to_slice())))
|
||||
}
|
||||
extern "C" fn ChainWatchInterfaceUtil_ChainWatchInterface_install_watch_outpoint(this_arg: *const c_void, mut outpoint: crate::c_types::derived::C2Tuple_Txidu32Z, out_script: crate::c_types::u8slice) {
|
||||
let (mut orig_outpoint_0, mut orig_outpoint_1) = outpoint.to_rust(); let mut local_outpoint = (::bitcoin::hash_types::Txid::from_slice(&orig_outpoint_0.data[..]).unwrap(), orig_outpoint_1);
|
||||
unsafe { &mut *(this_arg as *mut nativeChainWatchInterfaceUtil) }.install_watch_outpoint(local_outpoint, &::bitcoin::blockdata::script::Script::from(Vec::from(out_script.to_slice())))
|
||||
}
|
||||
extern "C" fn ChainWatchInterfaceUtil_ChainWatchInterface_watch_all_txn(this_arg: *const c_void) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChainWatchInterfaceUtil) }.watch_all_txn()
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn ChainWatchInterfaceUtil_ChainWatchInterface_get_chain_utxo(this_arg: *const c_void, mut genesis_hash: crate::c_types::ThirtyTwoBytes, mut _unspent_tx_output_identifier: u64) -> crate::c_types::derived::CResult_C2Tuple_Scriptu64ZChainErrorZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeChainWatchInterfaceUtil) }.get_chain_utxo(::bitcoin::hash_types::BlockHash::from_slice(&genesis_hash.data[..]).unwrap(), _unspent_tx_output_identifier);
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = o; let mut local_ret_0 = (orig_ret_0_0.into_bytes().into(), orig_ret_0_1).into(); local_ret_0 }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::chain::chaininterface::ChainError::native_into(e) }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn ChainWatchInterfaceUtil_ChainWatchInterface_filter_block(this_arg: *const c_void, block: crate::c_types::u8slice) -> crate::c_types::derived::CVec_usizeZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeChainWatchInterfaceUtil) }.filter_block(&::bitcoin::consensus::encode::deserialize(block.to_slice()).unwrap());
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { item }); };
|
||||
local_ret.into()
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn ChainWatchInterfaceUtil_ChainWatchInterface_reentered(this_arg: *const c_void) -> usize {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeChainWatchInterfaceUtil) }.reentered();
|
||||
ret
|
||||
}
|
||||
|
||||
/// Creates a new ChainWatchInterfaceUtil for the given network
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchInterfaceUtil_new(mut network: crate::bitcoin::network::Network) -> crate::chain::chaininterface::ChainWatchInterfaceUtil {
|
||||
let mut ret = lightning::chain::chaininterface::ChainWatchInterfaceUtil::new(network.into_bitcoin());
|
||||
crate::chain::chaininterface::ChainWatchInterfaceUtil { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Checks if a given transaction matches the current filter.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChainWatchInterfaceUtil_does_match_tx(this_arg: &ChainWatchInterfaceUtil, tx: crate::c_types::Transaction) -> bool {
|
||||
let mut ret = unsafe { &*this_arg.inner }.does_match_tx(&tx.into_bitcoin());
|
||||
ret
|
||||
}
|
||||
|
938
lightning-c-bindings/src/chain/keysinterface.rs
Normal file
938
lightning-c-bindings/src/chain/keysinterface.rs
Normal file
|
@ -0,0 +1,938 @@
|
|||
//! keysinterface provides keys into rust-lightning and defines some useful enums which describe
|
||||
//! spendable on-chain outputs which the user owns and is responsible for using just as any other
|
||||
//! on-chain output which is theirs.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
/// When on-chain outputs are created by rust-lightning (which our counterparty is not able to
|
||||
/// claim at any point in the future) an event is generated which you must track and be able to
|
||||
/// spend on-chain. The information needed to do this is provided in this enum, including the
|
||||
/// outpoint describing which txid and output index is available, the full output which exists at
|
||||
/// that txid/index, and any keys or other information required to sign.
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub enum SpendableOutputDescriptor {
|
||||
/// An output to a script which was provided via KeysInterface, thus you should already know
|
||||
/// how to spend it. No keys are provided as rust-lightning was never given any keys - only the
|
||||
/// script_pubkey as it appears in the output.
|
||||
/// These may include outputs from a transaction punishing our counterparty or claiming an HTLC
|
||||
/// on-chain using the payment preimage or after it has timed out.
|
||||
StaticOutput {
|
||||
outpoint: crate::chain::transaction::OutPoint,
|
||||
output: crate::c_types::TxOut,
|
||||
},
|
||||
/// An output to a P2WSH script which can be spent with a single signature after a CSV delay.
|
||||
///
|
||||
/// The witness in the spending input should be:
|
||||
/// <BIP 143 signature> <empty vector> (MINIMALIF standard rule) <provided witnessScript>
|
||||
///
|
||||
/// Note that the nSequence field in the spending input must be set to to_self_delay
|
||||
/// (which means the transaction is not broadcastable until at least to_self_delay
|
||||
/// blocks after the outpoint confirms).
|
||||
///
|
||||
/// These are generally the result of a \"revocable\" output to us, spendable only by us unless
|
||||
/// it is an output from an old state which we broadcast (which should never happen).
|
||||
///
|
||||
/// To derive the delayed_payment key which is used to sign for this input, you must pass the
|
||||
/// local delayed_payment_base_key (ie the private key which corresponds to the pubkey in
|
||||
/// ChannelKeys::pubkeys().delayed_payment_basepoint) and the provided per_commitment_point to
|
||||
/// chan_utils::derive_private_key. The public key can be generated without the secret key
|
||||
/// using chan_utils::derive_public_key and only the delayed_payment_basepoint which appears in
|
||||
/// ChannelKeys::pubkeys().
|
||||
///
|
||||
/// To derive the remote_revocation_pubkey provided here (which is used in the witness
|
||||
/// script generation), you must pass the remote revocation_basepoint (which appears in the
|
||||
/// call to ChannelKeys::on_accept) and the provided per_commitment point
|
||||
/// to chan_utils::derive_public_revocation_key.
|
||||
///
|
||||
/// The witness script which is hashed and included in the output script_pubkey may be
|
||||
/// regenerated by passing the revocation_pubkey (derived as above), our delayed_payment pubkey
|
||||
/// (derived as above), and the to_self_delay contained here to
|
||||
/// chan_utils::get_revokeable_redeemscript.
|
||||
DynamicOutputP2WSH {
|
||||
outpoint: crate::chain::transaction::OutPoint,
|
||||
per_commitment_point: crate::c_types::PublicKey,
|
||||
to_self_delay: u16,
|
||||
output: crate::c_types::TxOut,
|
||||
key_derivation_params: crate::c_types::derived::C2Tuple_u64u64Z,
|
||||
remote_revocation_pubkey: crate::c_types::PublicKey,
|
||||
},
|
||||
/// An output to a P2WPKH, spendable exclusively by our payment key (ie the private key which
|
||||
/// corresponds to the public key in ChannelKeys::pubkeys().payment_point).
|
||||
/// The witness in the spending input, is, thus, simply:
|
||||
/// <BIP 143 signature> <payment key>
|
||||
///
|
||||
/// These are generally the result of our counterparty having broadcast the current state,
|
||||
/// allowing us to claim the non-HTLC-encumbered outputs immediately.
|
||||
StaticOutputRemotePayment {
|
||||
outpoint: crate::chain::transaction::OutPoint,
|
||||
output: crate::c_types::TxOut,
|
||||
key_derivation_params: crate::c_types::derived::C2Tuple_u64u64Z,
|
||||
},
|
||||
}
|
||||
use lightning::chain::keysinterface::SpendableOutputDescriptor as nativeSpendableOutputDescriptor;
|
||||
impl SpendableOutputDescriptor {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn to_native(&self) -> nativeSpendableOutputDescriptor {
|
||||
match self {
|
||||
SpendableOutputDescriptor::StaticOutput {ref outpoint, ref output, } => {
|
||||
let mut outpoint_nonref = (*outpoint).clone();
|
||||
let mut output_nonref = (*output).clone();
|
||||
nativeSpendableOutputDescriptor::StaticOutput {
|
||||
outpoint: *unsafe { Box::from_raw(outpoint_nonref.take_ptr()) },
|
||||
output: output_nonref.into_rust(),
|
||||
}
|
||||
},
|
||||
SpendableOutputDescriptor::DynamicOutputP2WSH {ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref remote_revocation_pubkey, } => {
|
||||
let mut outpoint_nonref = (*outpoint).clone();
|
||||
let mut per_commitment_point_nonref = (*per_commitment_point).clone();
|
||||
let mut to_self_delay_nonref = (*to_self_delay).clone();
|
||||
let mut output_nonref = (*output).clone();
|
||||
let mut key_derivation_params_nonref = (*key_derivation_params).clone();
|
||||
let (mut orig_key_derivation_params_nonref_0, mut orig_key_derivation_params_nonref_1) = key_derivation_params_nonref.to_rust(); let mut local_key_derivation_params_nonref = (orig_key_derivation_params_nonref_0, orig_key_derivation_params_nonref_1);
|
||||
let mut remote_revocation_pubkey_nonref = (*remote_revocation_pubkey).clone();
|
||||
nativeSpendableOutputDescriptor::DynamicOutputP2WSH {
|
||||
outpoint: *unsafe { Box::from_raw(outpoint_nonref.take_ptr()) },
|
||||
per_commitment_point: per_commitment_point_nonref.into_rust(),
|
||||
to_self_delay: to_self_delay_nonref,
|
||||
output: output_nonref.into_rust(),
|
||||
key_derivation_params: local_key_derivation_params_nonref,
|
||||
remote_revocation_pubkey: remote_revocation_pubkey_nonref.into_rust(),
|
||||
}
|
||||
},
|
||||
SpendableOutputDescriptor::StaticOutputRemotePayment {ref outpoint, ref output, ref key_derivation_params, } => {
|
||||
let mut outpoint_nonref = (*outpoint).clone();
|
||||
let mut output_nonref = (*output).clone();
|
||||
let mut key_derivation_params_nonref = (*key_derivation_params).clone();
|
||||
let (mut orig_key_derivation_params_nonref_0, mut orig_key_derivation_params_nonref_1) = key_derivation_params_nonref.to_rust(); let mut local_key_derivation_params_nonref = (orig_key_derivation_params_nonref_0, orig_key_derivation_params_nonref_1);
|
||||
nativeSpendableOutputDescriptor::StaticOutputRemotePayment {
|
||||
outpoint: *unsafe { Box::from_raw(outpoint_nonref.take_ptr()) },
|
||||
output: output_nonref.into_rust(),
|
||||
key_derivation_params: local_key_derivation_params_nonref,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn into_native(self) -> nativeSpendableOutputDescriptor {
|
||||
match self {
|
||||
SpendableOutputDescriptor::StaticOutput {mut outpoint, mut output, } => {
|
||||
nativeSpendableOutputDescriptor::StaticOutput {
|
||||
outpoint: *unsafe { Box::from_raw(outpoint.take_ptr()) },
|
||||
output: output.into_rust(),
|
||||
}
|
||||
},
|
||||
SpendableOutputDescriptor::DynamicOutputP2WSH {mut outpoint, mut per_commitment_point, mut to_self_delay, mut output, mut key_derivation_params, mut remote_revocation_pubkey, } => {
|
||||
let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params.to_rust(); let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1);
|
||||
nativeSpendableOutputDescriptor::DynamicOutputP2WSH {
|
||||
outpoint: *unsafe { Box::from_raw(outpoint.take_ptr()) },
|
||||
per_commitment_point: per_commitment_point.into_rust(),
|
||||
to_self_delay: to_self_delay,
|
||||
output: output.into_rust(),
|
||||
key_derivation_params: local_key_derivation_params,
|
||||
remote_revocation_pubkey: remote_revocation_pubkey.into_rust(),
|
||||
}
|
||||
},
|
||||
SpendableOutputDescriptor::StaticOutputRemotePayment {mut outpoint, mut output, mut key_derivation_params, } => {
|
||||
let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params.to_rust(); let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1);
|
||||
nativeSpendableOutputDescriptor::StaticOutputRemotePayment {
|
||||
outpoint: *unsafe { Box::from_raw(outpoint.take_ptr()) },
|
||||
output: output.into_rust(),
|
||||
key_derivation_params: local_key_derivation_params,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn from_native(native: &nativeSpendableOutputDescriptor) -> Self {
|
||||
match native {
|
||||
nativeSpendableOutputDescriptor::StaticOutput {ref outpoint, ref output, } => {
|
||||
let mut outpoint_nonref = (*outpoint).clone();
|
||||
let mut output_nonref = (*output).clone();
|
||||
SpendableOutputDescriptor::StaticOutput {
|
||||
outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint_nonref)), is_owned: true },
|
||||
output: crate::c_types::TxOut::from_rust(output_nonref),
|
||||
}
|
||||
},
|
||||
nativeSpendableOutputDescriptor::DynamicOutputP2WSH {ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref remote_revocation_pubkey, } => {
|
||||
let mut outpoint_nonref = (*outpoint).clone();
|
||||
let mut per_commitment_point_nonref = (*per_commitment_point).clone();
|
||||
let mut to_self_delay_nonref = (*to_self_delay).clone();
|
||||
let mut output_nonref = (*output).clone();
|
||||
let mut key_derivation_params_nonref = (*key_derivation_params).clone();
|
||||
let (mut orig_key_derivation_params_nonref_0, mut orig_key_derivation_params_nonref_1) = key_derivation_params_nonref; let mut local_key_derivation_params_nonref = (orig_key_derivation_params_nonref_0, orig_key_derivation_params_nonref_1).into();
|
||||
let mut remote_revocation_pubkey_nonref = (*remote_revocation_pubkey).clone();
|
||||
SpendableOutputDescriptor::DynamicOutputP2WSH {
|
||||
outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint_nonref)), is_owned: true },
|
||||
per_commitment_point: crate::c_types::PublicKey::from_rust(&per_commitment_point_nonref),
|
||||
to_self_delay: to_self_delay_nonref,
|
||||
output: crate::c_types::TxOut::from_rust(output_nonref),
|
||||
key_derivation_params: local_key_derivation_params_nonref,
|
||||
remote_revocation_pubkey: crate::c_types::PublicKey::from_rust(&remote_revocation_pubkey_nonref),
|
||||
}
|
||||
},
|
||||
nativeSpendableOutputDescriptor::StaticOutputRemotePayment {ref outpoint, ref output, ref key_derivation_params, } => {
|
||||
let mut outpoint_nonref = (*outpoint).clone();
|
||||
let mut output_nonref = (*output).clone();
|
||||
let mut key_derivation_params_nonref = (*key_derivation_params).clone();
|
||||
let (mut orig_key_derivation_params_nonref_0, mut orig_key_derivation_params_nonref_1) = key_derivation_params_nonref; let mut local_key_derivation_params_nonref = (orig_key_derivation_params_nonref_0, orig_key_derivation_params_nonref_1).into();
|
||||
SpendableOutputDescriptor::StaticOutputRemotePayment {
|
||||
outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint_nonref)), is_owned: true },
|
||||
output: crate::c_types::TxOut::from_rust(output_nonref),
|
||||
key_derivation_params: local_key_derivation_params_nonref,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn native_into(native: nativeSpendableOutputDescriptor) -> Self {
|
||||
match native {
|
||||
nativeSpendableOutputDescriptor::StaticOutput {mut outpoint, mut output, } => {
|
||||
SpendableOutputDescriptor::StaticOutput {
|
||||
outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint)), is_owned: true },
|
||||
output: crate::c_types::TxOut::from_rust(output),
|
||||
}
|
||||
},
|
||||
nativeSpendableOutputDescriptor::DynamicOutputP2WSH {mut outpoint, mut per_commitment_point, mut to_self_delay, mut output, mut key_derivation_params, mut remote_revocation_pubkey, } => {
|
||||
let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params; let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1).into();
|
||||
SpendableOutputDescriptor::DynamicOutputP2WSH {
|
||||
outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint)), is_owned: true },
|
||||
per_commitment_point: crate::c_types::PublicKey::from_rust(&per_commitment_point),
|
||||
to_self_delay: to_self_delay,
|
||||
output: crate::c_types::TxOut::from_rust(output),
|
||||
key_derivation_params: local_key_derivation_params,
|
||||
remote_revocation_pubkey: crate::c_types::PublicKey::from_rust(&remote_revocation_pubkey),
|
||||
}
|
||||
},
|
||||
nativeSpendableOutputDescriptor::StaticOutputRemotePayment {mut outpoint, mut output, mut key_derivation_params, } => {
|
||||
let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params; let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1).into();
|
||||
SpendableOutputDescriptor::StaticOutputRemotePayment {
|
||||
outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint)), is_owned: true },
|
||||
output: crate::c_types::TxOut::from_rust(output),
|
||||
key_derivation_params: local_key_derivation_params,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn SpendableOutputDescriptor_free(this_ptr: SpendableOutputDescriptor) { }
|
||||
/// Set of lightning keys needed to operate a channel as described in BOLT 3.
|
||||
///
|
||||
/// Signing services could be implemented on a hardware wallet. In this case,
|
||||
/// the current ChannelKeys would be a front-end on top of a communication
|
||||
/// channel connected to your secure device and lightning key material wouldn't
|
||||
/// reside on a hot server. Nevertheless, a this deployment would still need
|
||||
/// to trust the ChannelManager to avoid loss of funds as this latest component
|
||||
/// could ask to sign commitment transaction with HTLCs paying to attacker pubkeys.
|
||||
///
|
||||
/// A more secure iteration would be to use hashlock (or payment points) to pair
|
||||
/// invoice/incoming HTLCs with outgoing HTLCs to implement a no-trust-ChannelManager
|
||||
/// at the price of more state and computation on the hardware wallet side. In the future,
|
||||
/// we are looking forward to design such interface.
|
||||
///
|
||||
/// In any case, ChannelMonitor or fallback watchtowers are always going to be trusted
|
||||
/// to act, as liveness and breach reply correctness are always going to be hard requirements
|
||||
/// of LN security model, orthogonal of key management issues.
|
||||
///
|
||||
/// If you're implementing a custom signer, you almost certainly want to implement
|
||||
/// Readable/Writable to serialize out a unique reference to this set of keys so
|
||||
/// that you can serialize the full ChannelManager object.
|
||||
///
|
||||
#[repr(C)]
|
||||
pub struct ChannelKeys {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Gets the per-commitment point for a specific commitment number
|
||||
///
|
||||
/// Note that the commitment number starts at (1 << 48) - 1 and counts backwards.
|
||||
#[must_use]
|
||||
pub get_per_commitment_point: extern "C" fn (this_arg: *const c_void, idx: u64) -> crate::c_types::PublicKey,
|
||||
/// Gets the commitment secret for a specific commitment number as part of the revocation process
|
||||
///
|
||||
/// An external signer implementation should error here if the commitment was already signed
|
||||
/// and should refuse to sign it in the future.
|
||||
///
|
||||
/// May be called more than once for the same index.
|
||||
///
|
||||
/// Note that the commitment number starts at (1 << 48) - 1 and counts backwards.
|
||||
/// TODO: return a Result so we can signal a validation error
|
||||
#[must_use]
|
||||
pub release_commitment_secret: extern "C" fn (this_arg: *const c_void, idx: u64) -> crate::c_types::ThirtyTwoBytes,
|
||||
/// Gets the local channel public keys and basepoints
|
||||
pub pubkeys: crate::ln::chan_utils::ChannelPublicKeys,
|
||||
/// Fill in the pubkeys field as a reference to it will be given to Rust after this returns
|
||||
/// Note that this takes a pointer to this object, not the this_ptr like other methods do
|
||||
/// This function pointer may be NULL if pubkeys is filled in when this object is created and never needs updating.
|
||||
pub set_pubkeys: Option<extern "C" fn(&ChannelKeys)>,
|
||||
/// Gets arbitrary identifiers describing the set of keys which are provided back to you in
|
||||
/// some SpendableOutputDescriptor types. These should be sufficient to identify this
|
||||
/// ChannelKeys object uniquely and lookup or re-derive its keys.
|
||||
#[must_use]
|
||||
pub key_derivation_params: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::C2Tuple_u64u64Z,
|
||||
/// Create a signature for a remote commitment transaction and associated HTLC transactions.
|
||||
///
|
||||
/// Note that if signing fails or is rejected, the channel will be force-closed.
|
||||
#[must_use]
|
||||
pub sign_remote_commitment: extern "C" fn (this_arg: *const c_void, feerate_per_kw: u32, commitment_tx: crate::c_types::Transaction, keys: &crate::ln::chan_utils::PreCalculatedTxCreationKeys, htlcs: crate::c_types::derived::CVec_HTLCOutputInCommitmentZ) -> crate::c_types::derived::CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ,
|
||||
/// Create a signature for a local commitment transaction. This will only ever be called with
|
||||
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
|
||||
/// that it will not be called multiple times.
|
||||
/// An external signer implementation should check that the commitment has not been revoked.
|
||||
#[must_use]
|
||||
pub sign_local_commitment: extern "C" fn (this_arg: *const c_void, local_commitment_tx: &crate::ln::chan_utils::LocalCommitmentTransaction) -> crate::c_types::derived::CResult_SignatureNoneZ,
|
||||
/// Create a signature for each HTLC transaction spending a local commitment transaction.
|
||||
///
|
||||
/// Unlike sign_local_commitment, this may be called multiple times with *different*
|
||||
/// local_commitment_tx values. While this will never be called with a revoked
|
||||
/// local_commitment_tx, it is possible that it is called with the second-latest
|
||||
/// local_commitment_tx (only if we haven't yet revoked it) if some watchtower/secondary
|
||||
/// ChannelMonitor decided to broadcast before it had been updated to the latest.
|
||||
///
|
||||
/// Either an Err should be returned, or a Vec with one entry for each HTLC which exists in
|
||||
/// local_commitment_tx. For those HTLCs which have transaction_output_index set to None
|
||||
/// (implying they were considered dust at the time the commitment transaction was negotiated),
|
||||
/// a corresponding None should be included in the return value. All other positions in the
|
||||
/// return value must contain a signature.
|
||||
#[must_use]
|
||||
pub sign_local_commitment_htlc_transactions: extern "C" fn (this_arg: *const c_void, local_commitment_tx: &crate::ln::chan_utils::LocalCommitmentTransaction) -> crate::c_types::derived::CResult_CVec_SignatureZNoneZ,
|
||||
/// Create a signature for the given input in a transaction spending an HTLC or commitment
|
||||
/// transaction output when our counterparty broadcasts an old state.
|
||||
///
|
||||
/// A justice transaction may claim multiples outputs at the same time if timelocks are
|
||||
/// similar, but only a signature for the input at index `input` should be signed for here.
|
||||
/// It may be called multiples time for same output(s) if a fee-bump is needed with regards
|
||||
/// to an upcoming timelock expiration.
|
||||
///
|
||||
/// Amount is value of the output spent by this input, committed to in the BIP 143 signature.
|
||||
///
|
||||
/// per_commitment_key is revocation secret which was provided by our counterparty when they
|
||||
/// revoked the state which they eventually broadcast. It's not a _local_ secret key and does
|
||||
/// not allow the spending of any funds by itself (you need our local revocation_secret to do
|
||||
/// so).
|
||||
///
|
||||
/// htlc holds HTLC elements (hash, timelock) if the output being spent is a HTLC output, thus
|
||||
/// changing the format of the witness script (which is committed to in the BIP 143
|
||||
/// signatures).
|
||||
#[must_use]
|
||||
pub sign_justice_transaction: extern "C" fn (this_arg: *const c_void, justice_tx: crate::c_types::Transaction, input: usize, amount: u64, per_commitment_key: *const [u8; 32], htlc: &crate::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ,
|
||||
/// Create a signature for a claiming transaction for a HTLC output on a remote commitment
|
||||
/// transaction, either offered or received.
|
||||
///
|
||||
/// Such a transaction may claim multiples offered outputs at same time if we know the
|
||||
/// preimage for each when we create it, but only the input at index `input` should be
|
||||
/// signed for here. It may be called multiple times for same output(s) if a fee-bump is
|
||||
/// needed with regards to an upcoming timelock expiration.
|
||||
///
|
||||
/// Witness_script is either a offered or received script as defined in BOLT3 for HTLC
|
||||
/// outputs.
|
||||
///
|
||||
/// Amount is value of the output spent by this input, committed to in the BIP 143 signature.
|
||||
///
|
||||
/// Per_commitment_point is the dynamic point corresponding to the channel state
|
||||
/// detected onchain. It has been generated by our counterparty and is used to derive
|
||||
/// channel state keys, which are then included in the witness script and committed to in the
|
||||
/// BIP 143 signature.
|
||||
#[must_use]
|
||||
pub sign_remote_htlc_transaction: extern "C" fn (this_arg: *const c_void, htlc_tx: crate::c_types::Transaction, input: usize, amount: u64, per_commitment_point: crate::c_types::PublicKey, htlc: &crate::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ,
|
||||
/// Create a signature for a (proposed) closing transaction.
|
||||
///
|
||||
/// Note that, due to rounding, there may be one \"missing\" satoshi, and either party may have
|
||||
/// chosen to forgo their output as dust.
|
||||
#[must_use]
|
||||
pub sign_closing_transaction: extern "C" fn (this_arg: *const c_void, closing_tx: crate::c_types::Transaction) -> crate::c_types::derived::CResult_SignatureNoneZ,
|
||||
/// Signs a channel announcement message with our funding key, proving it comes from one
|
||||
/// of the channel participants.
|
||||
///
|
||||
/// Note that if this fails or is rejected, the channel will not be publicly announced and
|
||||
/// our counterparty may (though likely will not) close the channel on us for violating the
|
||||
/// protocol.
|
||||
#[must_use]
|
||||
pub sign_channel_announcement: extern "C" fn (this_arg: *const c_void, msg: &crate::ln::msgs::UnsignedChannelAnnouncement) -> crate::c_types::derived::CResult_SignatureNoneZ,
|
||||
/// Set the remote channel basepoints and remote/local to_self_delay.
|
||||
/// This is done immediately on incoming channels and as soon as the channel is accepted on outgoing channels.
|
||||
///
|
||||
/// We bind local_to_self_delay late here for API convenience.
|
||||
///
|
||||
/// Will be called before any signatures are applied.
|
||||
pub on_accept: extern "C" fn (this_arg: *mut c_void, channel_points: &crate::ln::chan_utils::ChannelPublicKeys, remote_to_self_delay: u16, local_to_self_delay: u16),
|
||||
pub clone: Option<extern "C" fn (this_arg: *const c_void) -> *mut c_void>,
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
unsafe impl Send for ChannelKeys {}
|
||||
impl Clone for ChannelKeys {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
this_arg: if let Some(f) = self.clone { (f)(self.this_arg) } else { self.this_arg },
|
||||
get_per_commitment_point: self.get_per_commitment_point.clone(),
|
||||
release_commitment_secret: self.release_commitment_secret.clone(),
|
||||
pubkeys: self.pubkeys.clone(),
|
||||
set_pubkeys: self.set_pubkeys.clone(),
|
||||
key_derivation_params: self.key_derivation_params.clone(),
|
||||
sign_remote_commitment: self.sign_remote_commitment.clone(),
|
||||
sign_local_commitment: self.sign_local_commitment.clone(),
|
||||
sign_local_commitment_htlc_transactions: self.sign_local_commitment_htlc_transactions.clone(),
|
||||
sign_justice_transaction: self.sign_justice_transaction.clone(),
|
||||
sign_remote_htlc_transaction: self.sign_remote_htlc_transaction.clone(),
|
||||
sign_closing_transaction: self.sign_closing_transaction.clone(),
|
||||
sign_channel_announcement: self.sign_channel_announcement.clone(),
|
||||
on_accept: self.on_accept.clone(),
|
||||
clone: self.clone.clone(),
|
||||
free: self.free.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::chain::keysinterface::ChannelKeys as rustChannelKeys;
|
||||
impl rustChannelKeys for ChannelKeys {
|
||||
fn get_per_commitment_point<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, idx: u64, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> bitcoin::secp256k1::key::PublicKey {
|
||||
let mut ret = (self.get_per_commitment_point)(self.this_arg, idx);
|
||||
ret.into_rust()
|
||||
}
|
||||
fn release_commitment_secret(&self, idx: u64) -> [u8; 32] {
|
||||
let mut ret = (self.release_commitment_secret)(self.this_arg, idx);
|
||||
ret.data
|
||||
}
|
||||
fn pubkeys(&self) -> &lightning::ln::chan_utils::ChannelPublicKeys {
|
||||
if let Some(f) = self.set_pubkeys {
|
||||
(f)(self);
|
||||
}
|
||||
unsafe { &*self.pubkeys.inner }
|
||||
}
|
||||
fn key_derivation_params(&self) -> (u64, u64) {
|
||||
let mut ret = (self.key_derivation_params)(self.this_arg);
|
||||
let (mut orig_ret_0, mut orig_ret_1) = ret.to_rust(); let mut local_ret = (orig_ret_0, orig_ret_1);
|
||||
local_ret
|
||||
}
|
||||
fn sign_remote_commitment<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &bitcoin::blockdata::transaction::Transaction, keys: &lightning::ln::chan_utils::PreCalculatedTxCreationKeys, htlcs: &[&lightning::ln::chan_utils::HTLCOutputInCommitment], _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<(bitcoin::secp256k1::Signature, Vec<bitcoin::secp256k1::Signature>), ()> {
|
||||
let mut local_commitment_tx = ::bitcoin::consensus::encode::serialize(commitment_tx);
|
||||
let mut local_htlcs = Vec::new(); for item in htlcs.iter() { local_htlcs.push( { crate::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { ( (&(**item) as *const _) as *mut _) }, is_owned: false } }); };
|
||||
let mut ret = (self.sign_remote_commitment)(self.this_arg, feerate_per_kw, crate::c_types::Transaction::from_slice(&local_commitment_tx), &crate::ln::chan_utils::PreCalculatedTxCreationKeys { inner: unsafe { (keys as *const _) as *mut _ }, is_owned: false }, local_htlcs.into());
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (*unsafe { Box::from_raw(ret.contents.result.take_ptr()) }).to_rust(); let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.into_rust().drain(..) { local_orig_ret_0_1.push( { item.into_rust() }); }; let mut local_ret_0 = (orig_ret_0_0.into_rust(), local_orig_ret_0_1); local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(ret.contents.err.take_ptr()) })*/ })};
|
||||
local_ret
|
||||
}
|
||||
fn sign_local_commitment<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, local_commitment_tx: &lightning::ln::chan_utils::LocalCommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
|
||||
let mut ret = (self.sign_local_commitment)(self.this_arg, &crate::ln::chan_utils::LocalCommitmentTransaction { inner: unsafe { (local_commitment_tx as *const _) as *mut _ }, is_owned: false });
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(ret.contents.result.take_ptr()) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(ret.contents.err.take_ptr()) })*/ })};
|
||||
local_ret
|
||||
}
|
||||
fn sign_local_commitment_htlc_transactions<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, local_commitment_tx: &lightning::ln::chan_utils::LocalCommitmentTransaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<Vec<Option<bitcoin::secp256k1::Signature>>, ()> {
|
||||
let mut ret = (self.sign_local_commitment_htlc_transactions)(self.this_arg, &crate::ln::chan_utils::LocalCommitmentTransaction { inner: unsafe { (local_commitment_tx as *const _) as *mut _ }, is_owned: false });
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { let mut local_ret_0 = Vec::new(); for mut item in (*unsafe { Box::from_raw(ret.contents.result.take_ptr()) }).into_rust().drain(..) { local_ret_0.push( { let mut local_ret_0_0 = if item.is_null() { None } else { Some( { item.into_rust() }) }; local_ret_0_0 }); }; local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(ret.contents.err.take_ptr()) })*/ })};
|
||||
local_ret
|
||||
}
|
||||
fn sign_justice_transaction<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, justice_tx: &bitcoin::blockdata::transaction::Transaction, input: usize, amount: u64, per_commitment_key: &bitcoin::secp256k1::key::SecretKey, htlc: &Option<lightning::ln::chan_utils::HTLCOutputInCommitment>, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
|
||||
let mut local_justice_tx = ::bitcoin::consensus::encode::serialize(justice_tx);
|
||||
let mut local_htlc = &crate::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (if htlc.is_none() { std::ptr::null() } else { { (htlc.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
|
||||
let mut ret = (self.sign_justice_transaction)(self.this_arg, crate::c_types::Transaction::from_slice(&local_justice_tx), input, amount, per_commitment_key.as_ref(), local_htlc);
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(ret.contents.result.take_ptr()) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(ret.contents.err.take_ptr()) })*/ })};
|
||||
local_ret
|
||||
}
|
||||
fn sign_remote_htlc_transaction<T:bitcoin::secp256k1::Signing + bitcoin::secp256k1::Verification>(&self, htlc_tx: &bitcoin::blockdata::transaction::Transaction, input: usize, amount: u64, per_commitment_point: &bitcoin::secp256k1::key::PublicKey, htlc: &lightning::ln::chan_utils::HTLCOutputInCommitment, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
|
||||
let mut local_htlc_tx = ::bitcoin::consensus::encode::serialize(htlc_tx);
|
||||
let mut ret = (self.sign_remote_htlc_transaction)(self.this_arg, crate::c_types::Transaction::from_slice(&local_htlc_tx), input, amount, crate::c_types::PublicKey::from_rust(&per_commitment_point), &crate::ln::chan_utils::HTLCOutputInCommitment { inner: unsafe { (htlc as *const _) as *mut _ }, is_owned: false });
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(ret.contents.result.take_ptr()) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(ret.contents.err.take_ptr()) })*/ })};
|
||||
local_ret
|
||||
}
|
||||
fn sign_closing_transaction<T:bitcoin::secp256k1::Signing>(&self, closing_tx: &bitcoin::blockdata::transaction::Transaction, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
|
||||
let mut local_closing_tx = ::bitcoin::consensus::encode::serialize(closing_tx);
|
||||
let mut ret = (self.sign_closing_transaction)(self.this_arg, crate::c_types::Transaction::from_slice(&local_closing_tx));
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(ret.contents.result.take_ptr()) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(ret.contents.err.take_ptr()) })*/ })};
|
||||
local_ret
|
||||
}
|
||||
fn sign_channel_announcement<T:bitcoin::secp256k1::Signing>(&self, msg: &lightning::ln::msgs::UnsignedChannelAnnouncement, _secp_ctx: &bitcoin::secp256k1::Secp256k1<T>) -> Result<bitcoin::secp256k1::Signature, ()> {
|
||||
let mut ret = (self.sign_channel_announcement)(self.this_arg, &crate::ln::msgs::UnsignedChannelAnnouncement { inner: unsafe { (msg as *const _) as *mut _ }, is_owned: false });
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { (*unsafe { Box::from_raw(ret.contents.result.take_ptr()) }).into_rust() }), false => Err( { () /*(*unsafe { Box::from_raw(ret.contents.err.take_ptr()) })*/ })};
|
||||
local_ret
|
||||
}
|
||||
fn on_accept(&mut self, channel_points: &lightning::ln::chan_utils::ChannelPublicKeys, remote_to_self_delay: u16, local_to_self_delay: u16) {
|
||||
(self.on_accept)(self.this_arg, &crate::ln::chan_utils::ChannelPublicKeys { inner: unsafe { (channel_points as *const _) as *mut _ }, is_owned: false }, remote_to_self_delay, local_to_self_delay)
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for ChannelKeys {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelKeys_free(this_ptr: ChannelKeys) { }
|
||||
impl Drop for ChannelKeys {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// A trait to describe an object which can get user secrets and key material.
|
||||
#[repr(C)]
|
||||
pub struct KeysInterface {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Get node secret key (aka node_id or network_key)
|
||||
#[must_use]
|
||||
pub get_node_secret: extern "C" fn (this_arg: *const c_void) -> crate::c_types::SecretKey,
|
||||
/// Get destination redeemScript to encumber static protocol exit points.
|
||||
#[must_use]
|
||||
pub get_destination_script: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_u8Z,
|
||||
/// Get shutdown_pubkey to use as PublicKey at channel closure
|
||||
#[must_use]
|
||||
pub get_shutdown_pubkey: extern "C" fn (this_arg: *const c_void) -> crate::c_types::PublicKey,
|
||||
/// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you
|
||||
/// restarted with some stale data!
|
||||
#[must_use]
|
||||
pub get_channel_keys: extern "C" fn (this_arg: *const c_void, inbound: bool, channel_value_satoshis: u64) -> crate::chain::keysinterface::ChannelKeys,
|
||||
/// Gets a unique, cryptographically-secure, random 32 byte value. This is used for encrypting
|
||||
/// onion packets and for temporary channel IDs. There is no requirement that these be
|
||||
/// persisted anywhere, though they must be unique across restarts.
|
||||
#[must_use]
|
||||
pub get_secure_random_bytes: extern "C" fn (this_arg: *const c_void) -> crate::c_types::ThirtyTwoBytes,
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
unsafe impl Send for KeysInterface {}
|
||||
unsafe impl Sync for KeysInterface {}
|
||||
|
||||
use lightning::chain::keysinterface::KeysInterface as rustKeysInterface;
|
||||
impl rustKeysInterface for KeysInterface {
|
||||
type ChanKeySigner = crate::chain::keysinterface::ChannelKeys;
|
||||
fn get_node_secret(&self) -> bitcoin::secp256k1::key::SecretKey {
|
||||
let mut ret = (self.get_node_secret)(self.this_arg);
|
||||
ret.into_rust()
|
||||
}
|
||||
fn get_destination_script(&self) -> bitcoin::blockdata::script::Script {
|
||||
let mut ret = (self.get_destination_script)(self.this_arg);
|
||||
::bitcoin::blockdata::script::Script::from(ret.into_rust())
|
||||
}
|
||||
fn get_shutdown_pubkey(&self) -> bitcoin::secp256k1::key::PublicKey {
|
||||
let mut ret = (self.get_shutdown_pubkey)(self.this_arg);
|
||||
ret.into_rust()
|
||||
}
|
||||
fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner {
|
||||
let mut ret = (self.get_channel_keys)(self.this_arg, inbound, channel_value_satoshis);
|
||||
ret
|
||||
}
|
||||
fn get_secure_random_bytes(&self) -> [u8; 32] {
|
||||
let mut ret = (self.get_secure_random_bytes)(self.this_arg);
|
||||
ret.data
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for KeysInterface {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn KeysInterface_free(this_ptr: KeysInterface) { }
|
||||
impl Drop for KeysInterface {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::chain::keysinterface::InMemoryChannelKeys as nativeInMemoryChannelKeysImport;
|
||||
type nativeInMemoryChannelKeys = nativeInMemoryChannelKeysImport;
|
||||
|
||||
/// A simple implementation of ChannelKeys that just keeps the private keys in memory.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct InMemoryChannelKeys {
|
||||
/// Nearly everyhwere, 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 nativeInMemoryChannelKeys,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for InMemoryChannelKeys {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_free(this_ptr: InMemoryChannelKeys) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn InMemoryChannelKeys_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeInMemoryChannelKeys); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl InMemoryChannelKeys {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeInMemoryChannelKeys {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for InMemoryChannelKeys {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn InMemoryChannelKeys_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeInMemoryChannelKeys)).clone() })) as *mut c_void
|
||||
}
|
||||
/// Private key of anchor tx
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_get_funding_key(this_ptr: &InMemoryChannelKeys) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.funding_key;
|
||||
(*inner_val).as_ref()
|
||||
}
|
||||
/// Private key of anchor tx
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_set_funding_key(this_ptr: &mut InMemoryChannelKeys, mut val: crate::c_types::SecretKey) {
|
||||
unsafe { &mut *this_ptr.inner }.funding_key = val.into_rust();
|
||||
}
|
||||
/// Local secret key for blinded revocation pubkey
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_get_revocation_base_key(this_ptr: &InMemoryChannelKeys) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.revocation_base_key;
|
||||
(*inner_val).as_ref()
|
||||
}
|
||||
/// Local secret key for blinded revocation pubkey
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_set_revocation_base_key(this_ptr: &mut InMemoryChannelKeys, mut val: crate::c_types::SecretKey) {
|
||||
unsafe { &mut *this_ptr.inner }.revocation_base_key = val.into_rust();
|
||||
}
|
||||
/// Local secret key used for our balance in remote-broadcasted commitment transactions
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_get_payment_key(this_ptr: &InMemoryChannelKeys) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.payment_key;
|
||||
(*inner_val).as_ref()
|
||||
}
|
||||
/// Local secret key used for our balance in remote-broadcasted commitment transactions
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_set_payment_key(this_ptr: &mut InMemoryChannelKeys, mut val: crate::c_types::SecretKey) {
|
||||
unsafe { &mut *this_ptr.inner }.payment_key = val.into_rust();
|
||||
}
|
||||
/// Local secret key used in HTLC tx
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_get_delayed_payment_base_key(this_ptr: &InMemoryChannelKeys) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.delayed_payment_base_key;
|
||||
(*inner_val).as_ref()
|
||||
}
|
||||
/// Local secret key used in HTLC tx
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_set_delayed_payment_base_key(this_ptr: &mut InMemoryChannelKeys, mut val: crate::c_types::SecretKey) {
|
||||
unsafe { &mut *this_ptr.inner }.delayed_payment_base_key = val.into_rust();
|
||||
}
|
||||
/// Local htlc secret key used in commitment tx htlc outputs
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_get_htlc_base_key(this_ptr: &InMemoryChannelKeys) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.htlc_base_key;
|
||||
(*inner_val).as_ref()
|
||||
}
|
||||
/// Local htlc secret key used in commitment tx htlc outputs
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_set_htlc_base_key(this_ptr: &mut InMemoryChannelKeys, mut val: crate::c_types::SecretKey) {
|
||||
unsafe { &mut *this_ptr.inner }.htlc_base_key = val.into_rust();
|
||||
}
|
||||
/// Commitment seed
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_get_commitment_seed(this_ptr: &InMemoryChannelKeys) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.commitment_seed;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// Commitment seed
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_set_commitment_seed(this_ptr: &mut InMemoryChannelKeys, mut val: crate::c_types::ThirtyTwoBytes) {
|
||||
unsafe { &mut *this_ptr.inner }.commitment_seed = val.data;
|
||||
}
|
||||
/// Create a new InMemoryChannelKeys
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_new(mut funding_key: crate::c_types::SecretKey, mut revocation_base_key: crate::c_types::SecretKey, mut payment_key: crate::c_types::SecretKey, mut delayed_payment_base_key: crate::c_types::SecretKey, mut htlc_base_key: crate::c_types::SecretKey, mut commitment_seed: crate::c_types::ThirtyTwoBytes, mut channel_value_satoshis: u64, mut key_derivation_params: crate::c_types::derived::C2Tuple_u64u64Z) -> crate::chain::keysinterface::InMemoryChannelKeys {
|
||||
let (mut orig_key_derivation_params_0, mut orig_key_derivation_params_1) = key_derivation_params.to_rust(); let mut local_key_derivation_params = (orig_key_derivation_params_0, orig_key_derivation_params_1);
|
||||
let mut ret = lightning::chain::keysinterface::InMemoryChannelKeys::new(&bitcoin::secp256k1::Secp256k1::new(), funding_key.into_rust(), revocation_base_key.into_rust(), payment_key.into_rust(), delayed_payment_base_key.into_rust(), htlc_base_key.into_rust(), commitment_seed.data, channel_value_satoshis, local_key_derivation_params);
|
||||
crate::chain::keysinterface::InMemoryChannelKeys { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Remote pubkeys.
|
||||
/// Will panic if on_accept wasn't called.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_remote_pubkeys(this_arg: &InMemoryChannelKeys) -> crate::ln::chan_utils::ChannelPublicKeys {
|
||||
let mut ret = unsafe { &*this_arg.inner }.remote_pubkeys();
|
||||
crate::ln::chan_utils::ChannelPublicKeys { inner: unsafe { ( (&(*ret) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
|
||||
/// The to_self_delay value specified by our counterparty and applied on locally-broadcastable
|
||||
/// transactions, ie the amount of time that we have to wait to recover our funds if we
|
||||
/// broadcast a transaction. You'll likely want to pass this to the
|
||||
/// ln::chan_utils::build*_transaction functions when signing local transactions.
|
||||
/// Will panic if on_accept wasn't called.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_remote_to_self_delay(this_arg: &InMemoryChannelKeys) -> u16 {
|
||||
let mut ret = unsafe { &*this_arg.inner }.remote_to_self_delay();
|
||||
ret
|
||||
}
|
||||
|
||||
/// The to_self_delay value specified by us and applied on transactions broadcastable
|
||||
/// by our counterparty, ie the amount of time that they have to wait to recover their funds
|
||||
/// if they broadcast a transaction.
|
||||
/// Will panic if on_accept wasn't called.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_local_to_self_delay(this_arg: &InMemoryChannelKeys) -> u16 {
|
||||
let mut ret = unsafe { &*this_arg.inner }.local_to_self_delay();
|
||||
ret
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_as_ChannelKeys(this_arg: *const InMemoryChannelKeys) -> crate::chain::keysinterface::ChannelKeys {
|
||||
crate::chain::keysinterface::ChannelKeys {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
get_per_commitment_point: InMemoryChannelKeys_ChannelKeys_get_per_commitment_point,
|
||||
release_commitment_secret: InMemoryChannelKeys_ChannelKeys_release_commitment_secret,
|
||||
|
||||
pubkeys: crate::ln::chan_utils::ChannelPublicKeys { inner: std::ptr::null_mut(), is_owned: true },
|
||||
set_pubkeys: Some(InMemoryChannelKeys_ChannelKeys_set_pubkeys),
|
||||
key_derivation_params: InMemoryChannelKeys_ChannelKeys_key_derivation_params,
|
||||
sign_remote_commitment: InMemoryChannelKeys_ChannelKeys_sign_remote_commitment,
|
||||
sign_local_commitment: InMemoryChannelKeys_ChannelKeys_sign_local_commitment,
|
||||
sign_local_commitment_htlc_transactions: InMemoryChannelKeys_ChannelKeys_sign_local_commitment_htlc_transactions,
|
||||
sign_justice_transaction: InMemoryChannelKeys_ChannelKeys_sign_justice_transaction,
|
||||
sign_remote_htlc_transaction: InMemoryChannelKeys_ChannelKeys_sign_remote_htlc_transaction,
|
||||
sign_closing_transaction: InMemoryChannelKeys_ChannelKeys_sign_closing_transaction,
|
||||
sign_channel_announcement: InMemoryChannelKeys_ChannelKeys_sign_channel_announcement,
|
||||
on_accept: InMemoryChannelKeys_ChannelKeys_on_accept,
|
||||
clone: Some(InMemoryChannelKeys_clone_void),
|
||||
}
|
||||
}
|
||||
use lightning::chain::keysinterface::ChannelKeys as ChannelKeysTraitImport;
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_get_per_commitment_point(this_arg: *const c_void, mut idx: u64) -> crate::c_types::PublicKey {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.get_per_commitment_point(idx, &bitcoin::secp256k1::Secp256k1::new());
|
||||
crate::c_types::PublicKey::from_rust(&ret)
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_release_commitment_secret(this_arg: *const c_void, mut idx: u64) -> crate::c_types::ThirtyTwoBytes {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.release_commitment_secret(idx);
|
||||
crate::c_types::ThirtyTwoBytes { data: ret }
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_pubkeys(this_arg: *const c_void) -> crate::ln::chan_utils::ChannelPublicKeys {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.pubkeys();
|
||||
crate::ln::chan_utils::ChannelPublicKeys { inner: unsafe { ( (&(*ret) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_set_pubkeys(trait_self_arg: &ChannelKeys) {
|
||||
// This is a bit race-y in the general case, but for our specific use-cases today, we're safe
|
||||
// Specifically, we must ensure that the first time we're called it can never be in parallel
|
||||
if trait_self_arg.pubkeys.inner.is_null() {
|
||||
unsafe { &mut *(trait_self_arg as *const ChannelKeys as *mut ChannelKeys) }.pubkeys = InMemoryChannelKeys_ChannelKeys_pubkeys(trait_self_arg.this_arg);
|
||||
}
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_key_derivation_params(this_arg: *const c_void) -> crate::c_types::derived::C2Tuple_u64u64Z {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.key_derivation_params();
|
||||
let (mut orig_ret_0, mut orig_ret_1) = ret; let mut local_ret = (orig_ret_0, orig_ret_1).into();
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_sign_remote_commitment(this_arg: *const c_void, mut feerate_per_kw: u32, commitment_tx: crate::c_types::Transaction, pre_keys: &crate::ln::chan_utils::PreCalculatedTxCreationKeys, mut htlcs: crate::c_types::derived::CVec_HTLCOutputInCommitmentZ) -> crate::c_types::derived::CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ {
|
||||
let mut local_htlcs = Vec::new(); for mut item in htlcs.as_slice().iter() { local_htlcs.push( { unsafe { &*item.inner } }); };
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.sign_remote_commitment(feerate_per_kw, &commitment_tx.into_bitcoin(), unsafe { &*pre_keys.inner }, &local_htlcs[..], &bitcoin::secp256k1::Secp256k1::new());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = o; let mut local_orig_ret_0_1 = Vec::new(); for item in orig_ret_0_1.drain(..) { local_orig_ret_0_1.push( { crate::c_types::Signature::from_rust(&item) }); }; let mut local_ret_0 = (crate::c_types::Signature::from_rust(&orig_ret_0_0), local_orig_ret_0_1.into()).into(); local_ret_0 }), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_sign_local_commitment(this_arg: *const c_void, local_commitment_tx: &crate::ln::chan_utils::LocalCommitmentTransaction) -> crate::c_types::derived::CResult_SignatureNoneZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.sign_local_commitment(unsafe { &*local_commitment_tx.inner }, &bitcoin::secp256k1::Secp256k1::new());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_sign_local_commitment_htlc_transactions(this_arg: *const c_void, local_commitment_tx: &crate::ln::chan_utils::LocalCommitmentTransaction) -> crate::c_types::derived::CResult_CVec_SignatureZNoneZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.sign_local_commitment_htlc_transactions(unsafe { &*local_commitment_tx.inner }, &bitcoin::secp256k1::Secp256k1::new());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let mut local_ret_0 = Vec::new(); for item in o.drain(..) { local_ret_0.push( { let mut local_ret_0_0 = if item.is_none() { crate::c_types::Signature::null() } else { { crate::c_types::Signature::from_rust(&(item.unwrap())) } }; local_ret_0_0 }); }; local_ret_0.into() }), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_sign_justice_transaction(this_arg: *const c_void, justice_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, per_commitment_key: *const [u8; 32], htlc: &crate::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ {
|
||||
let mut local_htlc = if htlc.inner.is_null() { None } else { Some((* { unsafe { &*htlc.inner } }).clone()) };
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.sign_justice_transaction(&justice_tx.into_bitcoin(), input, amount, &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *per_commitment_key}[..]).unwrap(), &local_htlc, &bitcoin::secp256k1::Secp256k1::new());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_sign_remote_htlc_transaction(this_arg: *const c_void, htlc_tx: crate::c_types::Transaction, mut input: usize, mut amount: u64, per_commitment_point: crate::c_types::PublicKey, htlc: &crate::ln::chan_utils::HTLCOutputInCommitment) -> crate::c_types::derived::CResult_SignatureNoneZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.sign_remote_htlc_transaction(&htlc_tx.into_bitcoin(), input, amount, &per_commitment_point.into_rust(), unsafe { &*htlc.inner }, &bitcoin::secp256k1::Secp256k1::new());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_sign_closing_transaction(this_arg: *const c_void, closing_tx: crate::c_types::Transaction) -> crate::c_types::derived::CResult_SignatureNoneZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.sign_closing_transaction(&closing_tx.into_bitcoin(), &bitcoin::secp256k1::Secp256k1::new());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_sign_channel_announcement(this_arg: *const c_void, msg: &crate::ln::msgs::UnsignedChannelAnnouncement) -> crate::c_types::derived::CResult_SignatureNoneZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.sign_channel_announcement(unsafe { &*msg.inner }, &bitcoin::secp256k1::Secp256k1::new());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::Signature::from_rust(&o) }), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }) };
|
||||
local_ret
|
||||
}
|
||||
extern "C" fn InMemoryChannelKeys_ChannelKeys_on_accept(this_arg: *mut c_void, channel_pubkeys: &crate::ln::chan_utils::ChannelPublicKeys, mut remote_to_self_delay: u16, mut local_to_self_delay: u16) {
|
||||
unsafe { &mut *(this_arg as *mut nativeInMemoryChannelKeys) }.on_accept(unsafe { &*channel_pubkeys.inner }, remote_to_self_delay, local_to_self_delay)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_write(obj: *const InMemoryChannelKeys) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InMemoryChannelKeys_read(ser: crate::c_types::u8slice) -> InMemoryChannelKeys {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
InMemoryChannelKeys { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
InMemoryChannelKeys { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::chain::keysinterface::KeysManager as nativeKeysManagerImport;
|
||||
type nativeKeysManager = nativeKeysManagerImport;
|
||||
|
||||
/// Simple KeysInterface implementor that takes a 32-byte seed for use as a BIP 32 extended key
|
||||
/// and derives keys from that.
|
||||
///
|
||||
/// Your node_id is seed/0'
|
||||
/// ChannelMonitor closes may use seed/1'
|
||||
/// Cooperative closes may use seed/2'
|
||||
/// The two close keys may be needed to claim on-chain funds!
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct KeysManager {
|
||||
/// Nearly everyhwere, 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 nativeKeysManager,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for KeysManager {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn KeysManager_free(this_ptr: KeysManager) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn KeysManager_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeKeysManager); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl KeysManager {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeKeysManager {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Constructs a KeysManager from a 32-byte seed. If the seed is in some way biased (eg your
|
||||
/// CSRNG is busted) this may panic (but more importantly, you will possibly lose funds).
|
||||
/// starting_time isn't strictly required to actually be a time, but it must absolutely,
|
||||
/// without a doubt, be unique to this instance. ie if you start multiple times with the same
|
||||
/// seed, starting_time must be unique to each run. Thus, the easiest way to achieve this is to
|
||||
/// simply use the current time (with very high precision).
|
||||
///
|
||||
/// The seed MUST be backed up safely prior to use so that the keys can be re-created, however,
|
||||
/// obviously, starting_time should be unique every time you reload the library - it is only
|
||||
/// used to generate new ephemeral key data (which will be stored by the individual channel if
|
||||
/// necessary).
|
||||
///
|
||||
/// Note that the seed is required to recover certain on-chain funds independent of
|
||||
/// ChannelMonitor data, though a current copy of ChannelMonitor data is also required for any
|
||||
/// channel, and some on-chain during-closing funds.
|
||||
///
|
||||
/// Note that until the 0.1 release there is no guarantee of backward compatibility between
|
||||
/// versions. Once the library is more fully supported, the docs will be updated to include a
|
||||
/// detailed description of the guarantee.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn KeysManager_new(seed: *const [u8; 32], mut network: crate::bitcoin::network::Network, mut starting_time_secs: u64, mut starting_time_nanos: u32) -> KeysManager {
|
||||
let mut ret = lightning::chain::keysinterface::KeysManager::new(unsafe { &*seed}, network.into_bitcoin(), starting_time_secs, starting_time_nanos);
|
||||
KeysManager { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Derive an old set of ChannelKeys for per-channel secrets based on a key derivation
|
||||
/// parameters.
|
||||
/// Key derivation parameters are accessible through a per-channel secrets
|
||||
/// ChannelKeys::key_derivation_params and is provided inside DynamicOuputP2WSH in case of
|
||||
/// onchain output detection for which a corresponding delayed_payment_key must be derived.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn KeysManager_derive_channel_keys(this_arg: &KeysManager, mut channel_value_satoshis: u64, mut params_1: u64, mut params_2: u64) -> crate::chain::keysinterface::InMemoryChannelKeys {
|
||||
let mut ret = unsafe { &*this_arg.inner }.derive_channel_keys(channel_value_satoshis, params_1, params_2);
|
||||
crate::chain::keysinterface::InMemoryChannelKeys { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn KeysManager_as_KeysInterface(this_arg: *const KeysManager) -> crate::chain::keysinterface::KeysInterface {
|
||||
crate::chain::keysinterface::KeysInterface {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
get_node_secret: KeysManager_KeysInterface_get_node_secret,
|
||||
get_destination_script: KeysManager_KeysInterface_get_destination_script,
|
||||
get_shutdown_pubkey: KeysManager_KeysInterface_get_shutdown_pubkey,
|
||||
get_channel_keys: KeysManager_KeysInterface_get_channel_keys,
|
||||
get_secure_random_bytes: KeysManager_KeysInterface_get_secure_random_bytes,
|
||||
}
|
||||
}
|
||||
use lightning::chain::keysinterface::KeysInterface as KeysInterfaceTraitImport;
|
||||
#[must_use]
|
||||
extern "C" fn KeysManager_KeysInterface_get_node_secret(this_arg: *const c_void) -> crate::c_types::SecretKey {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeKeysManager) }.get_node_secret();
|
||||
crate::c_types::SecretKey::from_rust(ret)
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn KeysManager_KeysInterface_get_destination_script(this_arg: *const c_void) -> crate::c_types::derived::CVec_u8Z {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeKeysManager) }.get_destination_script();
|
||||
ret.into_bytes().into()
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn KeysManager_KeysInterface_get_shutdown_pubkey(this_arg: *const c_void) -> crate::c_types::PublicKey {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeKeysManager) }.get_shutdown_pubkey();
|
||||
crate::c_types::PublicKey::from_rust(&ret)
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn KeysManager_KeysInterface_get_channel_keys(this_arg: *const c_void, mut _inbound: bool, mut channel_value_satoshis: u64) -> crate::chain::keysinterface::ChannelKeys {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeKeysManager) }.get_channel_keys(_inbound, channel_value_satoshis);
|
||||
let mut rust_obj = InMemoryChannelKeys { inner: Box::into_raw(Box::new(ret)), is_owned: true };
|
||||
let mut ret = InMemoryChannelKeys_as_ChannelKeys(&rust_obj);
|
||||
// We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn
|
||||
rust_obj.inner = std::ptr::null_mut();
|
||||
ret.free = Some(InMemoryChannelKeys_free_void);
|
||||
ret
|
||||
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn KeysManager_KeysInterface_get_secure_random_bytes(this_arg: *const c_void) -> crate::c_types::ThirtyTwoBytes {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeKeysManager) }.get_secure_random_bytes();
|
||||
crate::c_types::ThirtyTwoBytes { data: ret }
|
||||
}
|
||||
|
9
lightning-c-bindings/src/chain/mod.rs
Normal file
9
lightning-c-bindings/src/chain/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
//! Structs and traits which allow other parts of rust-lightning to interact with the blockchain.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
pub mod chaininterface;
|
||||
pub mod transaction;
|
||||
pub mod keysinterface;
|
110
lightning-c-bindings/src/chain/transaction.rs
Normal file
110
lightning-c-bindings/src/chain/transaction.rs
Normal file
|
@ -0,0 +1,110 @@
|
|||
//! Contains simple structs describing parts of transactions on the chain.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
|
||||
use lightning::chain::transaction::OutPoint as nativeOutPointImport;
|
||||
type nativeOutPoint = nativeOutPointImport;
|
||||
|
||||
/// A reference to a transaction output.
|
||||
///
|
||||
/// Differs from bitcoin::blockdata::transaction::OutPoint as the index is a u16 instead of u32
|
||||
/// due to LN's restrictions on index values. Should reduce (possibly) unsafe conversions this way.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct OutPoint {
|
||||
/// Nearly everyhwere, 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 nativeOutPoint,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for OutPoint {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_free(this_ptr: OutPoint) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn OutPoint_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeOutPoint); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl OutPoint {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeOutPoint {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for OutPoint {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn OutPoint_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeOutPoint)).clone() })) as *mut c_void
|
||||
}
|
||||
/// The referenced transaction's txid.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_get_txid(this_ptr: &OutPoint) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.txid;
|
||||
(*inner_val).as_inner()
|
||||
}
|
||||
/// The referenced transaction's txid.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_set_txid(this_ptr: &mut OutPoint, mut val: crate::c_types::ThirtyTwoBytes) {
|
||||
unsafe { &mut *this_ptr.inner }.txid = ::bitcoin::hash_types::Txid::from_slice(&val.data[..]).unwrap();
|
||||
}
|
||||
/// The index of the referenced output in its transaction's vout.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_get_index(this_ptr: &OutPoint) -> u16 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.index;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The index of the referenced output in its transaction's vout.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_set_index(this_ptr: &mut OutPoint, mut val: u16) {
|
||||
unsafe { &mut *this_ptr.inner }.index = val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_new(mut txid_arg: crate::c_types::ThirtyTwoBytes, mut index_arg: u16) -> OutPoint {
|
||||
OutPoint { inner: Box::into_raw(Box::new(nativeOutPoint {
|
||||
txid: ::bitcoin::hash_types::Txid::from_slice(&txid_arg.data[..]).unwrap(),
|
||||
index: index_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
/// Convert an `OutPoint` to a lightning channel id.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_to_channel_id(this_arg: &OutPoint) -> crate::c_types::ThirtyTwoBytes {
|
||||
let mut ret = unsafe { &*this_arg.inner }.to_channel_id();
|
||||
crate::c_types::ThirtyTwoBytes { data: ret }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_write(obj: *const OutPoint) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn OutPoint_read(ser: crate::c_types::u8slice) -> OutPoint {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
OutPoint { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
OutPoint { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
24
lightning-c-bindings/src/lib.rs
Normal file
24
lightning-c-bindings/src/lib.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
//!lightning
|
||||
//! Rust-Lightning, not Rusty's Lightning!
|
||||
//!
|
||||
//! A full-featured but also flexible lightning implementation, in library form. This allows the
|
||||
//! user (you) to decide how they wish to use it instead of being a fully self-contained daemon.
|
||||
//! This means there is no built-in threading/execution environment and it's up to the user to
|
||||
//! figure out how best to make networking happen/timers fire/things get written to disk/keys get
|
||||
//! generated/etc. This makes it a good candidate for tight integration into an existing wallet
|
||||
//! instead of having a rather-separate lightning appendage to a wallet.
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(unused_mut)]
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_unsafe)]
|
||||
#![allow(unused_braces)]
|
||||
mod c_types;
|
||||
mod bitcoin;
|
||||
pub mod util;
|
||||
pub mod chain;
|
||||
pub mod ln;
|
||||
pub mod routing;
|
745
lightning-c-bindings/src/ln/chan_utils.rs
Normal file
745
lightning-c-bindings/src/ln/chan_utils.rs
Normal file
|
@ -0,0 +1,745 @@
|
|||
//! Various utilities for building scripts and deriving keys related to channels. These are
|
||||
//! largely of interest for those implementing chain::keysinterface::ChannelKeys message signing
|
||||
//! by hand.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
/// Build the commitment secret from the seed and the commitment number
|
||||
#[no_mangle]
|
||||
pub extern "C" fn build_commitment_secret(commitment_seed: *const [u8; 32], mut idx: u64) -> crate::c_types::ThirtyTwoBytes {
|
||||
let mut ret = lightning::ln::chan_utils::build_commitment_secret(unsafe { &*commitment_seed}, idx);
|
||||
crate::c_types::ThirtyTwoBytes { data: ret }
|
||||
}
|
||||
|
||||
/// Derives a per-commitment-transaction private key (eg an htlc key or delayed_payment key)
|
||||
/// from the base secret and the per_commitment_point.
|
||||
///
|
||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||
/// generated (ie our own).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn derive_private_key(per_commitment_point: crate::c_types::PublicKey, base_secret: *const [u8; 32]) -> crate::c_types::derived::CResult_SecretKeySecpErrorZ {
|
||||
let mut ret = lightning::ln::chan_utils::derive_private_key(&bitcoin::secp256k1::Secp256k1::new(), &per_commitment_point.into_rust(), &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *base_secret}[..]).unwrap());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::SecretKey::from_rust(o) }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::c_types::Secp256k1Error::from_rust(e) }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Derives a per-commitment-transaction public key (eg an htlc key or a delayed_payment key)
|
||||
/// from the base point and the per_commitment_key. This is the public equivalent of
|
||||
/// derive_private_key - using only public keys to derive a public key instead of private keys.
|
||||
///
|
||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||
/// generated (ie our own).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn derive_public_key(per_commitment_point: crate::c_types::PublicKey, base_point: crate::c_types::PublicKey) -> crate::c_types::derived::CResult_PublicKeySecpErrorZ {
|
||||
let mut ret = lightning::ln::chan_utils::derive_public_key(&bitcoin::secp256k1::Secp256k1::new(), &per_commitment_point.into_rust(), &base_point.into_rust());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::PublicKey::from_rust(&o) }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::c_types::Secp256k1Error::from_rust(e) }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Derives a per-commitment-transaction revocation key from its constituent parts.
|
||||
///
|
||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||
/// generated (ie our own).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn derive_private_revocation_key(per_commitment_secret: *const [u8; 32], revocation_base_secret: *const [u8; 32]) -> crate::c_types::derived::CResult_SecretKeySecpErrorZ {
|
||||
let mut ret = lightning::ln::chan_utils::derive_private_revocation_key(&bitcoin::secp256k1::Secp256k1::new(), &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *per_commitment_secret}[..]).unwrap(), &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *revocation_base_secret}[..]).unwrap());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::SecretKey::from_rust(o) }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::c_types::Secp256k1Error::from_rust(e) }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Derives a per-commitment-transaction revocation public key from its constituent parts. This is
|
||||
/// the public equivalend of derive_private_revocation_key - using only public keys to derive a
|
||||
/// public key instead of private keys.
|
||||
///
|
||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||
/// generated (ie our own).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn derive_public_revocation_key(per_commitment_point: crate::c_types::PublicKey, revocation_base_point: crate::c_types::PublicKey) -> crate::c_types::derived::CResult_PublicKeySecpErrorZ {
|
||||
let mut ret = lightning::ln::chan_utils::derive_public_revocation_key(&bitcoin::secp256k1::Secp256k1::new(), &per_commitment_point.into_rust(), &revocation_base_point.into_rust());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::PublicKey::from_rust(&o) }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::c_types::Secp256k1Error::from_rust(e) }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
|
||||
use lightning::ln::chan_utils::TxCreationKeys as nativeTxCreationKeysImport;
|
||||
type nativeTxCreationKeys = nativeTxCreationKeysImport;
|
||||
|
||||
/// The set of public keys which are used in the creation of one commitment transaction.
|
||||
/// These are derived from the channel base keys and per-commitment data.
|
||||
///
|
||||
/// These keys are assumed to be good, either because the code derived them from
|
||||
/// channel basepoints via the new function, or they were obtained via
|
||||
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
|
||||
/// pre-calculated keys.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct TxCreationKeys {
|
||||
/// Nearly everyhwere, 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 nativeTxCreationKeys,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for TxCreationKeys {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_free(this_ptr: TxCreationKeys) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn TxCreationKeys_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeTxCreationKeys); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl TxCreationKeys {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeTxCreationKeys {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for TxCreationKeys {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn TxCreationKeys_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeTxCreationKeys)).clone() })) as *mut c_void
|
||||
}
|
||||
/// The per-commitment public key which was used to derive the other keys.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_get_per_commitment_point(this_ptr: &TxCreationKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.per_commitment_point;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The per-commitment public key which was used to derive the other keys.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_set_per_commitment_point(this_ptr: &mut TxCreationKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.per_commitment_point = val.into_rust();
|
||||
}
|
||||
/// The revocation key which is used to allow the owner of the commitment transaction to
|
||||
/// provide their counterparty the ability to punish them if they broadcast an old state.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_get_revocation_key(this_ptr: &TxCreationKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.revocation_key;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The revocation key which is used to allow the owner of the commitment transaction to
|
||||
/// provide their counterparty the ability to punish them if they broadcast an old state.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_set_revocation_key(this_ptr: &mut TxCreationKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.revocation_key = val.into_rust();
|
||||
}
|
||||
/// A's HTLC Key
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_get_a_htlc_key(this_ptr: &TxCreationKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.a_htlc_key;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// A's HTLC Key
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_set_a_htlc_key(this_ptr: &mut TxCreationKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.a_htlc_key = val.into_rust();
|
||||
}
|
||||
/// B's HTLC Key
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_get_b_htlc_key(this_ptr: &TxCreationKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.b_htlc_key;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// B's HTLC Key
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_set_b_htlc_key(this_ptr: &mut TxCreationKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.b_htlc_key = val.into_rust();
|
||||
}
|
||||
/// A's Payment Key (which isn't allowed to be spent from for some delay)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_get_a_delayed_payment_key(this_ptr: &TxCreationKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.a_delayed_payment_key;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// A's Payment Key (which isn't allowed to be spent from for some delay)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_set_a_delayed_payment_key(this_ptr: &mut TxCreationKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.a_delayed_payment_key = val.into_rust();
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_new(mut per_commitment_point_arg: crate::c_types::PublicKey, mut revocation_key_arg: crate::c_types::PublicKey, mut a_htlc_key_arg: crate::c_types::PublicKey, mut b_htlc_key_arg: crate::c_types::PublicKey, mut a_delayed_payment_key_arg: crate::c_types::PublicKey) -> TxCreationKeys {
|
||||
TxCreationKeys { inner: Box::into_raw(Box::new(nativeTxCreationKeys {
|
||||
per_commitment_point: per_commitment_point_arg.into_rust(),
|
||||
revocation_key: revocation_key_arg.into_rust(),
|
||||
a_htlc_key: a_htlc_key_arg.into_rust(),
|
||||
b_htlc_key: b_htlc_key_arg.into_rust(),
|
||||
a_delayed_payment_key: a_delayed_payment_key_arg.into_rust(),
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_write(obj: *const TxCreationKeys) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_read(ser: crate::c_types::u8slice) -> TxCreationKeys {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
TxCreationKeys { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
TxCreationKeys { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::chan_utils::PreCalculatedTxCreationKeys as nativePreCalculatedTxCreationKeysImport;
|
||||
type nativePreCalculatedTxCreationKeys = nativePreCalculatedTxCreationKeysImport;
|
||||
|
||||
/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
|
||||
/// in the signer.
|
||||
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
|
||||
/// information to re-derive them.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct PreCalculatedTxCreationKeys {
|
||||
/// Nearly everyhwere, 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 nativePreCalculatedTxCreationKeys,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for PreCalculatedTxCreationKeys {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PreCalculatedTxCreationKeys_free(this_ptr: PreCalculatedTxCreationKeys) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn PreCalculatedTxCreationKeys_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativePreCalculatedTxCreationKeys); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl PreCalculatedTxCreationKeys {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativePreCalculatedTxCreationKeys {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PreCalculatedTxCreationKeys_new(mut keys: crate::ln::chan_utils::TxCreationKeys) -> PreCalculatedTxCreationKeys {
|
||||
let mut ret = lightning::ln::chan_utils::PreCalculatedTxCreationKeys::new(*unsafe { Box::from_raw(keys.take_ptr()) });
|
||||
PreCalculatedTxCreationKeys { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// The pre-calculated transaction creation public keys.
|
||||
/// An external validating signer should not trust these keys.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PreCalculatedTxCreationKeys_trust_key_derivation(this_arg: &PreCalculatedTxCreationKeys) -> crate::ln::chan_utils::TxCreationKeys {
|
||||
let mut ret = unsafe { &*this_arg.inner }.trust_key_derivation();
|
||||
crate::ln::chan_utils::TxCreationKeys { inner: unsafe { ( (&(*ret) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
|
||||
/// The transaction per-commitment point
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PreCalculatedTxCreationKeys_per_commitment_point(this_arg: &PreCalculatedTxCreationKeys) -> crate::c_types::PublicKey {
|
||||
let mut ret = unsafe { &*this_arg.inner }.per_commitment_point();
|
||||
crate::c_types::PublicKey::from_rust(&*ret)
|
||||
}
|
||||
|
||||
|
||||
use lightning::ln::chan_utils::ChannelPublicKeys as nativeChannelPublicKeysImport;
|
||||
type nativeChannelPublicKeys = nativeChannelPublicKeysImport;
|
||||
|
||||
/// One counterparty's public keys which do not change over the life of a channel.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelPublicKeys {
|
||||
/// Nearly everyhwere, 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 nativeChannelPublicKeys,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelPublicKeys {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_free(this_ptr: ChannelPublicKeys) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelPublicKeys_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelPublicKeys); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelPublicKeys {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelPublicKeys {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for ChannelPublicKeys {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn ChannelPublicKeys_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelPublicKeys)).clone() })) as *mut c_void
|
||||
}
|
||||
/// The public key which is used to sign all commitment transactions, as it appears in the
|
||||
/// on-chain channel lock-in 2-of-2 multisig output.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_get_funding_pubkey(this_ptr: &ChannelPublicKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.funding_pubkey;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The public key which is used to sign all commitment transactions, as it appears in the
|
||||
/// on-chain channel lock-in 2-of-2 multisig output.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_set_funding_pubkey(this_ptr: &mut ChannelPublicKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.funding_pubkey = val.into_rust();
|
||||
}
|
||||
/// The base point which is used (with derive_public_revocation_key) to derive per-commitment
|
||||
/// revocation keys. This is combined with the per-commitment-secret generated by the
|
||||
/// counterparty to create a secret which the counterparty can reveal to revoke previous
|
||||
/// states.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_get_revocation_basepoint(this_ptr: &ChannelPublicKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.revocation_basepoint;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The base point which is used (with derive_public_revocation_key) to derive per-commitment
|
||||
/// revocation keys. This is combined with the per-commitment-secret generated by the
|
||||
/// counterparty to create a secret which the counterparty can reveal to revoke previous
|
||||
/// states.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_set_revocation_basepoint(this_ptr: &mut ChannelPublicKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.revocation_basepoint = val.into_rust();
|
||||
}
|
||||
/// The public key which receives our immediately spendable primary channel balance in
|
||||
/// remote-broadcasted commitment transactions. This key is static across every commitment
|
||||
/// transaction.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_get_payment_point(this_ptr: &ChannelPublicKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.payment_point;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The public key which receives our immediately spendable primary channel balance in
|
||||
/// remote-broadcasted commitment transactions. This key is static across every commitment
|
||||
/// transaction.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_set_payment_point(this_ptr: &mut ChannelPublicKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.payment_point = val.into_rust();
|
||||
}
|
||||
/// The base point which is used (with derive_public_key) to derive a per-commitment payment
|
||||
/// public key which receives non-HTLC-encumbered funds which are only available for spending
|
||||
/// after some delay (or can be claimed via the revocation path).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_get_delayed_payment_basepoint(this_ptr: &ChannelPublicKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.delayed_payment_basepoint;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The base point which is used (with derive_public_key) to derive a per-commitment payment
|
||||
/// public key which receives non-HTLC-encumbered funds which are only available for spending
|
||||
/// after some delay (or can be claimed via the revocation path).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_set_delayed_payment_basepoint(this_ptr: &mut ChannelPublicKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.delayed_payment_basepoint = val.into_rust();
|
||||
}
|
||||
/// The base point which is used (with derive_public_key) to derive a per-commitment public key
|
||||
/// which is used to encumber HTLC-in-flight outputs.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_get_htlc_basepoint(this_ptr: &ChannelPublicKeys) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.htlc_basepoint;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The base point which is used (with derive_public_key) to derive a per-commitment public key
|
||||
/// which is used to encumber HTLC-in-flight outputs.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_set_htlc_basepoint(this_ptr: &mut ChannelPublicKeys, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.htlc_basepoint = val.into_rust();
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_new(mut funding_pubkey_arg: crate::c_types::PublicKey, mut revocation_basepoint_arg: crate::c_types::PublicKey, mut payment_point_arg: crate::c_types::PublicKey, mut delayed_payment_basepoint_arg: crate::c_types::PublicKey, mut htlc_basepoint_arg: crate::c_types::PublicKey) -> ChannelPublicKeys {
|
||||
ChannelPublicKeys { inner: Box::into_raw(Box::new(nativeChannelPublicKeys {
|
||||
funding_pubkey: funding_pubkey_arg.into_rust(),
|
||||
revocation_basepoint: revocation_basepoint_arg.into_rust(),
|
||||
payment_point: payment_point_arg.into_rust(),
|
||||
delayed_payment_basepoint: delayed_payment_basepoint_arg.into_rust(),
|
||||
htlc_basepoint: htlc_basepoint_arg.into_rust(),
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_write(obj: *const ChannelPublicKeys) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelPublicKeys_read(ser: crate::c_types::u8slice) -> ChannelPublicKeys {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
ChannelPublicKeys { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
ChannelPublicKeys { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
/// Create a new TxCreationKeys from channel base points and the per-commitment point
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn TxCreationKeys_derive_new(per_commitment_point: crate::c_types::PublicKey, a_delayed_payment_base: crate::c_types::PublicKey, a_htlc_base: crate::c_types::PublicKey, b_revocation_base: crate::c_types::PublicKey, b_htlc_base: crate::c_types::PublicKey) -> crate::c_types::derived::CResult_TxCreationKeysSecpErrorZ {
|
||||
let mut ret = lightning::ln::chan_utils::TxCreationKeys::derive_new(&bitcoin::secp256k1::Secp256k1::new(), &per_commitment_point.into_rust(), &a_delayed_payment_base.into_rust(), &a_htlc_base.into_rust(), &b_revocation_base.into_rust(), &b_htlc_base.into_rust());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::ln::chan_utils::TxCreationKeys { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::c_types::Secp256k1Error::from_rust(e) }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// A script either spendable by the revocation
|
||||
/// key or the delayed_payment_key and satisfying the relative-locktime OP_CSV constrain.
|
||||
/// Encumbering a `to_local` output on a commitment transaction or 2nd-stage HTLC transactions.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn get_revokeable_redeemscript(revocation_key: crate::c_types::PublicKey, mut to_self_delay: u16, delayed_payment_key: crate::c_types::PublicKey) -> crate::c_types::derived::CVec_u8Z {
|
||||
let mut ret = lightning::ln::chan_utils::get_revokeable_redeemscript(&revocation_key.into_rust(), to_self_delay, &delayed_payment_key.into_rust());
|
||||
ret.into_bytes().into()
|
||||
}
|
||||
|
||||
|
||||
use lightning::ln::chan_utils::HTLCOutputInCommitment as nativeHTLCOutputInCommitmentImport;
|
||||
type nativeHTLCOutputInCommitment = nativeHTLCOutputInCommitmentImport;
|
||||
|
||||
/// Information about an HTLC as it appears in a commitment transaction
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct HTLCOutputInCommitment {
|
||||
/// Nearly everyhwere, 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 nativeHTLCOutputInCommitment,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for HTLCOutputInCommitment {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_free(this_ptr: HTLCOutputInCommitment) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn HTLCOutputInCommitment_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeHTLCOutputInCommitment); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl HTLCOutputInCommitment {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeHTLCOutputInCommitment {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for HTLCOutputInCommitment {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn HTLCOutputInCommitment_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeHTLCOutputInCommitment)).clone() })) as *mut c_void
|
||||
}
|
||||
/// Whether the HTLC was \"offered\" (ie outbound in relation to this commitment transaction).
|
||||
/// Note that this is not the same as whether it is ountbound *from us*. To determine that you
|
||||
/// need to compare this value to whether the commitment transaction in question is that of
|
||||
/// the remote party or our own.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_get_offered(this_ptr: &HTLCOutputInCommitment) -> bool {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.offered;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Whether the HTLC was \"offered\" (ie outbound in relation to this commitment transaction).
|
||||
/// Note that this is not the same as whether it is ountbound *from us*. To determine that you
|
||||
/// need to compare this value to whether the commitment transaction in question is that of
|
||||
/// the remote party or our own.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_set_offered(this_ptr: &mut HTLCOutputInCommitment, mut val: bool) {
|
||||
unsafe { &mut *this_ptr.inner }.offered = val;
|
||||
}
|
||||
/// The value, in msat, of the HTLC. The value as it appears in the commitment transaction is
|
||||
/// this divided by 1000.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_get_amount_msat(this_ptr: &HTLCOutputInCommitment) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.amount_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The value, in msat, of the HTLC. The value as it appears in the commitment transaction is
|
||||
/// this divided by 1000.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_set_amount_msat(this_ptr: &mut HTLCOutputInCommitment, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.amount_msat = val;
|
||||
}
|
||||
/// The CLTV lock-time at which this HTLC expires.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_get_cltv_expiry(this_ptr: &HTLCOutputInCommitment) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.cltv_expiry;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The CLTV lock-time at which this HTLC expires.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_set_cltv_expiry(this_ptr: &mut HTLCOutputInCommitment, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.cltv_expiry = val;
|
||||
}
|
||||
/// The hash of the preimage which unlocks this HTLC.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_get_payment_hash(this_ptr: &HTLCOutputInCommitment) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.payment_hash;
|
||||
&(*inner_val).0
|
||||
}
|
||||
/// The hash of the preimage which unlocks this HTLC.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_set_payment_hash(this_ptr: &mut HTLCOutputInCommitment, mut val: crate::c_types::ThirtyTwoBytes) {
|
||||
unsafe { &mut *this_ptr.inner }.payment_hash = ::lightning::ln::channelmanager::PaymentHash(val.data);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_write(obj: *const HTLCOutputInCommitment) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCOutputInCommitment_read(ser: crate::c_types::u8slice) -> HTLCOutputInCommitment {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
HTLCOutputInCommitment { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
HTLCOutputInCommitment { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
/// note here that 'a_revocation_key' is generated using b_revocation_basepoint and a's
|
||||
/// commitment secret. 'htlc' does *not* need to have its previous_output_index filled.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn get_htlc_redeemscript(htlc: &crate::ln::chan_utils::HTLCOutputInCommitment, keys: &crate::ln::chan_utils::TxCreationKeys) -> crate::c_types::derived::CVec_u8Z {
|
||||
let mut ret = lightning::ln::chan_utils::get_htlc_redeemscript(unsafe { &*htlc.inner }, unsafe { &*keys.inner });
|
||||
ret.into_bytes().into()
|
||||
}
|
||||
|
||||
/// Gets the redeemscript for a funding output from the two funding public keys.
|
||||
/// Note that the order of funding public keys does not matter.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn make_funding_redeemscript(a: crate::c_types::PublicKey, b: crate::c_types::PublicKey) -> crate::c_types::derived::CVec_u8Z {
|
||||
let mut ret = lightning::ln::chan_utils::make_funding_redeemscript(&a.into_rust(), &b.into_rust());
|
||||
ret.into_bytes().into()
|
||||
}
|
||||
|
||||
/// panics if htlc.transaction_output_index.is_none()!
|
||||
#[no_mangle]
|
||||
pub extern "C" fn build_htlc_transaction(prev_hash: *const [u8; 32], mut feerate_per_kw: u32, mut to_self_delay: u16, htlc: &crate::ln::chan_utils::HTLCOutputInCommitment, a_delayed_payment_key: crate::c_types::PublicKey, revocation_key: crate::c_types::PublicKey) -> crate::c_types::derived::CVec_u8Z {
|
||||
let mut ret = lightning::ln::chan_utils::build_htlc_transaction(&::bitcoin::hash_types::Txid::from_slice(&unsafe { &*prev_hash }[..]).unwrap(), feerate_per_kw, to_self_delay, unsafe { &*htlc.inner }, &a_delayed_payment_key.into_rust(), &revocation_key.into_rust());
|
||||
let mut local_ret = ::bitcoin::consensus::encode::serialize(&ret);
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
|
||||
use lightning::ln::chan_utils::LocalCommitmentTransaction as nativeLocalCommitmentTransactionImport;
|
||||
type nativeLocalCommitmentTransaction = nativeLocalCommitmentTransactionImport;
|
||||
|
||||
/// We use this to track local commitment transactions and put off signing them until we are ready
|
||||
/// to broadcast. This class can be used inside a signer implementation to generate a signature
|
||||
/// given the relevant secret key.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct LocalCommitmentTransaction {
|
||||
/// Nearly everyhwere, 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 nativeLocalCommitmentTransaction,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for LocalCommitmentTransaction {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_free(this_ptr: LocalCommitmentTransaction) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn LocalCommitmentTransaction_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeLocalCommitmentTransaction); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl LocalCommitmentTransaction {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeLocalCommitmentTransaction {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for LocalCommitmentTransaction {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn LocalCommitmentTransaction_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeLocalCommitmentTransaction)).clone() })) as *mut c_void
|
||||
}
|
||||
/// The commitment transaction itself, in unsigned form.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_get_unsigned_tx(this_ptr: &LocalCommitmentTransaction) -> crate::c_types::derived::CVec_u8Z {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.unsigned_tx;
|
||||
let mut local_inner_val = ::bitcoin::consensus::encode::serialize(inner_val);
|
||||
local_inner_val.into()
|
||||
}
|
||||
/// The commitment transaction itself, in unsigned form.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_set_unsigned_tx(this_ptr: &mut LocalCommitmentTransaction, mut val: crate::c_types::derived::CVec_u8Z) {
|
||||
unsafe { &mut *this_ptr.inner }.unsigned_tx = ::bitcoin::consensus::encode::deserialize(&val.into_rust()[..]).unwrap();
|
||||
}
|
||||
/// Our counterparty's signature for the transaction, above.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_get_their_sig(this_ptr: &LocalCommitmentTransaction) -> crate::c_types::Signature {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.their_sig;
|
||||
crate::c_types::Signature::from_rust(&(*inner_val))
|
||||
}
|
||||
/// Our counterparty's signature for the transaction, above.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_set_their_sig(this_ptr: &mut LocalCommitmentTransaction, mut val: crate::c_types::Signature) {
|
||||
unsafe { &mut *this_ptr.inner }.their_sig = val.into_rust();
|
||||
}
|
||||
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
|
||||
/// controlled by the channel initiator.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_get_feerate_per_kw(this_ptr: &LocalCommitmentTransaction) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.feerate_per_kw;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
|
||||
/// controlled by the channel initiator.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_set_feerate_per_kw(this_ptr: &mut LocalCommitmentTransaction, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.feerate_per_kw = val;
|
||||
}
|
||||
/// The HTLCs and remote htlc signatures which were included in this commitment transaction.
|
||||
///
|
||||
/// Note that this includes all HTLCs, including ones which were considered dust and not
|
||||
/// actually included in the transaction as it appears on-chain, but who's value is burned as
|
||||
/// fees and not included in the to_local or to_remote outputs.
|
||||
///
|
||||
/// The remote HTLC signatures in the second element will always be set for non-dust HTLCs, ie
|
||||
/// those for which transaction_output_index.is_some().
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_set_per_htlc(this_ptr: &mut LocalCommitmentTransaction, mut val: crate::c_types::derived::CVec_C2Tuple_HTLCOutputInCommitmentSignatureZZ) {
|
||||
let mut local_val = Vec::new(); for mut item in val.into_rust().drain(..) { local_val.push( { let (mut orig_val_0_0, mut orig_val_0_1) = item.to_rust(); let mut local_orig_val_0_1 = if orig_val_0_1.is_null() { None } else { Some( { orig_val_0_1.into_rust() }) }; let mut local_val_0 = (*unsafe { Box::from_raw(orig_val_0_0.take_ptr()) }, local_orig_val_0_1); local_val_0 }); };
|
||||
unsafe { &mut *this_ptr.inner }.per_htlc = local_val;
|
||||
}
|
||||
/// Generate a new LocalCommitmentTransaction based on a raw commitment transaction,
|
||||
/// remote signature and both parties keys.
|
||||
///
|
||||
/// The unsigned transaction outputs must be consistent with htlc_data. This function
|
||||
/// only checks that the shape and amounts are consistent, but does not check the scriptPubkey.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_new_missing_local_sig(mut unsigned_tx: crate::c_types::derived::CVec_u8Z, mut their_sig: crate::c_types::Signature, our_funding_key: crate::c_types::PublicKey, their_funding_key: crate::c_types::PublicKey, mut local_keys: crate::ln::chan_utils::TxCreationKeys, mut feerate_per_kw: u32, mut htlc_data: crate::c_types::derived::CVec_C2Tuple_HTLCOutputInCommitmentSignatureZZ) -> crate::ln::chan_utils::LocalCommitmentTransaction {
|
||||
let mut local_htlc_data = Vec::new(); for mut item in htlc_data.into_rust().drain(..) { local_htlc_data.push( { let (mut orig_htlc_data_0_0, mut orig_htlc_data_0_1) = item.to_rust(); let mut local_orig_htlc_data_0_1 = if orig_htlc_data_0_1.is_null() { None } else { Some( { orig_htlc_data_0_1.into_rust() }) }; let mut local_htlc_data_0 = (*unsafe { Box::from_raw(orig_htlc_data_0_0.take_ptr()) }, local_orig_htlc_data_0_1); local_htlc_data_0 }); };
|
||||
let mut ret = lightning::ln::chan_utils::LocalCommitmentTransaction::new_missing_local_sig(::bitcoin::consensus::encode::deserialize(&unsigned_tx.into_rust()[..]).unwrap(), their_sig.into_rust(), &our_funding_key.into_rust(), &their_funding_key.into_rust(), *unsafe { Box::from_raw(local_keys.take_ptr()) }, feerate_per_kw, local_htlc_data);
|
||||
crate::ln::chan_utils::LocalCommitmentTransaction { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// The pre-calculated transaction creation public keys.
|
||||
/// An external validating signer should not trust these keys.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_trust_key_derivation(this_arg: &LocalCommitmentTransaction) -> crate::ln::chan_utils::TxCreationKeys {
|
||||
let mut ret = unsafe { &*this_arg.inner }.trust_key_derivation();
|
||||
crate::ln::chan_utils::TxCreationKeys { inner: unsafe { ( (&(*ret) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
|
||||
/// Get the txid of the local commitment transaction contained in this
|
||||
/// LocalCommitmentTransaction
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_txid(this_arg: &LocalCommitmentTransaction) -> crate::c_types::ThirtyTwoBytes {
|
||||
let mut ret = unsafe { &*this_arg.inner }.txid();
|
||||
crate::c_types::ThirtyTwoBytes { data: ret.into_inner() }
|
||||
}
|
||||
|
||||
/// Gets our signature for the contained commitment transaction given our funding private key.
|
||||
///
|
||||
/// Funding key is your key included in the 2-2 funding_outpoint lock. Should be provided
|
||||
/// by your ChannelKeys.
|
||||
/// Funding redeemscript is script locking funding_outpoint. This is the mutlsig script
|
||||
/// between your own funding key and your counterparty's. Currently, this is provided in
|
||||
/// ChannelKeys::sign_local_commitment() calls directly.
|
||||
/// Channel value is amount locked in funding_outpoint.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_get_local_sig(this_arg: &LocalCommitmentTransaction, funding_key: *const [u8; 32], funding_redeemscript: crate::c_types::u8slice, mut channel_value_satoshis: u64) -> crate::c_types::Signature {
|
||||
let mut ret = unsafe { &*this_arg.inner }.get_local_sig(&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *funding_key}[..]).unwrap(), &::bitcoin::blockdata::script::Script::from(Vec::from(funding_redeemscript.to_slice())), channel_value_satoshis, &bitcoin::secp256k1::Secp256k1::new());
|
||||
crate::c_types::Signature::from_rust(&ret)
|
||||
}
|
||||
|
||||
/// Get a signature for each HTLC which was included in the commitment transaction (ie for
|
||||
/// which HTLCOutputInCommitment::transaction_output_index.is_some()).
|
||||
///
|
||||
/// The returned Vec has one entry for each HTLC, and in the same order. For HTLCs which were
|
||||
/// considered dust and not included, a None entry exists, for all others a signature is
|
||||
/// included.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_get_htlc_sigs(this_arg: &LocalCommitmentTransaction, htlc_base_key: *const [u8; 32], mut local_csv: u16) -> crate::c_types::derived::CResult_CVec_SignatureZNoneZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.get_htlc_sigs(&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *htlc_base_key}[..]).unwrap(), local_csv, &bitcoin::secp256k1::Secp256k1::new());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let mut local_ret_0 = Vec::new(); for item in o.drain(..) { local_ret_0.push( { let mut local_ret_0_0 = if item.is_none() { crate::c_types::Signature::null() } else { { crate::c_types::Signature::from_rust(&(item.unwrap())) } }; local_ret_0_0 }); }; local_ret_0.into() }), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_write(obj: *const LocalCommitmentTransaction) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LocalCommitmentTransaction_read(ser: crate::c_types::u8slice) -> LocalCommitmentTransaction {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
LocalCommitmentTransaction { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
LocalCommitmentTransaction { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
842
lightning-c-bindings/src/ln/channelmanager.rs
Normal file
842
lightning-c-bindings/src/ln/channelmanager.rs
Normal file
|
@ -0,0 +1,842 @@
|
|||
//! The top-level channel management and payment tracking stuff lives here.
|
||||
//!
|
||||
//! The ChannelManager is the main chunk of logic implementing the lightning protocol and is
|
||||
//! responsible for tracking which channels are open, HTLCs are in flight and reestablishing those
|
||||
//! upon reconnect to the relevant peer(s).
|
||||
//!
|
||||
//! It does not manage routing logic (see routing::router::get_route for that) nor does it manage constructing
|
||||
//! on-chain transactions (it only monitors the chain to watch for any force-closes that might
|
||||
//! imply it needs to fail HTLCs/payments/channels it manages).
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
|
||||
use lightning::ln::channelmanager::ChannelManager as nativeChannelManagerImport;
|
||||
type nativeChannelManager = nativeChannelManagerImport<crate::chain::keysinterface::ChannelKeys, crate::ln::channelmonitor::ManyChannelMonitor, crate::chain::chaininterface::BroadcasterInterface, crate::chain::keysinterface::KeysInterface, crate::chain::chaininterface::FeeEstimator, crate::util::logger::Logger>;
|
||||
|
||||
/// Manager which keeps track of a number of channels and sends messages to the appropriate
|
||||
/// channel, also tracking HTLC preimages and forwarding onion packets appropriately.
|
||||
///
|
||||
/// Implements ChannelMessageHandler, handling the multi-channel parts and passing things through
|
||||
/// to individual Channels.
|
||||
///
|
||||
/// Implements Writeable to write out all channel state to disk. Implies peer_disconnected() for
|
||||
/// all peers during write/read (though does not modify this instance, only the instance being
|
||||
/// serialized). This will result in any channels which have not yet exchanged funding_created (ie
|
||||
/// called funding_transaction_generated for outbound channels).
|
||||
///
|
||||
/// Note that you can be a bit lazier about writing out ChannelManager than you can be with
|
||||
/// ChannelMonitors. With ChannelMonitors you MUST write each monitor update out to disk before
|
||||
/// returning from ManyChannelMonitor::add_/update_monitor, with ChannelManagers, writing updates
|
||||
/// happens out-of-band (and will prevent any other ChannelManager operations from occurring during
|
||||
/// the serialization process). If the deserialized version is out-of-date compared to the
|
||||
/// ChannelMonitors passed by reference to read(), those channels will be force-closed based on the
|
||||
/// ChannelMonitor state and no funds will be lost (mod on-chain transaction fees).
|
||||
///
|
||||
/// Note that the deserializer is only implemented for (Sha256dHash, ChannelManager), which
|
||||
/// tells you the last block hash which was block_connect()ed. You MUST rescan any blocks along
|
||||
/// the \"reorg path\" (ie call block_disconnected() until you get to a common block and then call
|
||||
/// block_connected() to step towards your best block) upon deserialization before using the
|
||||
/// object!
|
||||
///
|
||||
/// Note that ChannelManager is responsible for tracking liveness of its channels and generating
|
||||
/// ChannelUpdate messages informing peers that the channel is temporarily disabled. To avoid
|
||||
/// spam due to quick disconnection/reconnection, updates are not sent until the channel has been
|
||||
/// offline for a full minute. In order to track this, you must call
|
||||
/// timer_chan_freshness_every_min roughly once per minute, though it doesn't have to be perfect.
|
||||
///
|
||||
/// Rather than using a plain ChannelManager, it is preferable to use either a SimpleArcChannelManager
|
||||
/// a SimpleRefChannelManager, for conciseness. See their documentation for more details, but
|
||||
/// essentially you should default to using a SimpleRefChannelManager, and use a
|
||||
/// SimpleArcChannelManager when you require a ChannelManager with a static lifetime, such as when
|
||||
/// you're using lightning-net-tokio.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelManager {
|
||||
/// Nearly everyhwere, 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 nativeChannelManager,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelManager {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_free(this_ptr: ChannelManager) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelManager_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelManager); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelManager {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelManager {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::channelmanager::ChannelDetails as nativeChannelDetailsImport;
|
||||
type nativeChannelDetails = nativeChannelDetailsImport;
|
||||
|
||||
/// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelDetails {
|
||||
/// Nearly everyhwere, 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 nativeChannelDetails,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelDetails {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_free(this_ptr: ChannelDetails) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelDetails_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelDetails); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelDetails {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelDetails {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
|
||||
/// thereafter this is the txid of the funding transaction xor the funding transaction output).
|
||||
/// Note that this means this value is *not* persistent - it can change once during the
|
||||
/// lifetime of the channel.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_get_channel_id(this_ptr: &ChannelDetails) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.channel_id;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
|
||||
/// thereafter this is the txid of the funding transaction xor the funding transaction output).
|
||||
/// Note that this means this value is *not* persistent - it can change once during the
|
||||
/// lifetime of the channel.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_set_channel_id(this_ptr: &mut ChannelDetails, mut val: crate::c_types::ThirtyTwoBytes) {
|
||||
unsafe { &mut *this_ptr.inner }.channel_id = val.data;
|
||||
}
|
||||
/// The node_id of our counterparty
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_get_remote_network_id(this_ptr: &ChannelDetails) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.remote_network_id;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The node_id of our counterparty
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_set_remote_network_id(this_ptr: &mut ChannelDetails, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.remote_network_id = val.into_rust();
|
||||
}
|
||||
/// The Features the channel counterparty provided upon last connection.
|
||||
/// Useful for routing as it is the most up-to-date copy of the counterparty's features and
|
||||
/// many routing-relevant features are present in the init context.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_get_counterparty_features(this_ptr: &ChannelDetails) -> crate::ln::features::InitFeatures {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.counterparty_features;
|
||||
crate::ln::features::InitFeatures { inner: &mut (*inner_val), is_owned: false }
|
||||
}
|
||||
/// The Features the channel counterparty provided upon last connection.
|
||||
/// Useful for routing as it is the most up-to-date copy of the counterparty's features and
|
||||
/// many routing-relevant features are present in the init context.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_set_counterparty_features(this_ptr: &mut ChannelDetails, mut val: crate::ln::features::InitFeatures) {
|
||||
unsafe { &mut *this_ptr.inner }.counterparty_features = *unsafe { Box::from_raw(val.take_ptr()) };
|
||||
}
|
||||
/// The value, in satoshis, of this channel as appears in the funding output
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_get_channel_value_satoshis(this_ptr: &ChannelDetails) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.channel_value_satoshis;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The value, in satoshis, of this channel as appears in the funding output
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_set_channel_value_satoshis(this_ptr: &mut ChannelDetails, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.channel_value_satoshis = val;
|
||||
}
|
||||
/// The user_id passed in to create_channel, or 0 if the channel was inbound.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_get_user_id(this_ptr: &ChannelDetails) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.user_id;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The user_id passed in to create_channel, or 0 if the channel was inbound.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_set_user_id(this_ptr: &mut ChannelDetails, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.user_id = val;
|
||||
}
|
||||
/// The available outbound capacity for sending HTLCs to the remote peer. This does not include
|
||||
/// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
|
||||
/// available for inclusion in new outbound HTLCs). This further does not include any pending
|
||||
/// outgoing HTLCs which are awaiting some other resolution to be sent.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_get_outbound_capacity_msat(this_ptr: &ChannelDetails) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.outbound_capacity_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The available outbound capacity for sending HTLCs to the remote peer. This does not include
|
||||
/// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
|
||||
/// available for inclusion in new outbound HTLCs). This further does not include any pending
|
||||
/// outgoing HTLCs which are awaiting some other resolution to be sent.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_set_outbound_capacity_msat(this_ptr: &mut ChannelDetails, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.outbound_capacity_msat = val;
|
||||
}
|
||||
/// The available inbound capacity for the remote peer to send HTLCs to us. This does not
|
||||
/// include any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
|
||||
/// available for inclusion in new inbound HTLCs).
|
||||
/// Note that there are some corner cases not fully handled here, so the actual available
|
||||
/// inbound capacity may be slightly higher than this.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_get_inbound_capacity_msat(this_ptr: &ChannelDetails) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.inbound_capacity_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The available inbound capacity for the remote peer to send HTLCs to us. This does not
|
||||
/// include any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
|
||||
/// available for inclusion in new inbound HTLCs).
|
||||
/// Note that there are some corner cases not fully handled here, so the actual available
|
||||
/// inbound capacity may be slightly higher than this.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_set_inbound_capacity_msat(this_ptr: &mut ChannelDetails, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.inbound_capacity_msat = val;
|
||||
}
|
||||
/// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
|
||||
/// the peer is connected, and (c) no monitor update failure is pending resolution.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_get_is_live(this_ptr: &ChannelDetails) -> bool {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_live;
|
||||
(*inner_val)
|
||||
}
|
||||
/// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
|
||||
/// the peer is connected, and (c) no monitor update failure is pending resolution.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelDetails_set_is_live(this_ptr: &mut ChannelDetails, mut val: bool) {
|
||||
unsafe { &mut *this_ptr.inner }.is_live = val;
|
||||
}
|
||||
|
||||
use lightning::ln::channelmanager::PaymentSendFailure as nativePaymentSendFailureImport;
|
||||
type nativePaymentSendFailure = nativePaymentSendFailureImport;
|
||||
|
||||
/// If a payment fails to send, it can be in one of several states. This enum is returned as the
|
||||
/// Err() type describing which state the payment is in, see the description of individual enum
|
||||
/// states for more.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct PaymentSendFailure {
|
||||
/// Nearly everyhwere, 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 nativePaymentSendFailure,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for PaymentSendFailure {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PaymentSendFailure_free(this_ptr: PaymentSendFailure) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn PaymentSendFailure_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativePaymentSendFailure); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl PaymentSendFailure {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativePaymentSendFailure {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Constructs a new ChannelManager to hold several channels and route between them.
|
||||
///
|
||||
/// This is the main \"logic hub\" for all channel-related actions, and implements
|
||||
/// ChannelMessageHandler.
|
||||
///
|
||||
/// Non-proportional fees are fixed according to our risk using the provided fee estimator.
|
||||
///
|
||||
/// panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`!
|
||||
///
|
||||
/// Users must provide the current blockchain height from which to track onchain channel
|
||||
/// funding outpoints and send payments with reliable timelocks.
|
||||
///
|
||||
/// Users need to notify the new ChannelManager when a new block is connected or
|
||||
/// disconnected using its `block_connected` and `block_disconnected` methods.
|
||||
/// However, rather than calling these methods directly, the user should register
|
||||
/// the ChannelManager as a listener to the BlockNotifier and call the BlockNotifier's
|
||||
/// `block_(dis)connected` methods, which will notify all registered listeners in one
|
||||
/// go.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_new(mut network: crate::bitcoin::network::Network, mut fee_est: crate::chain::chaininterface::FeeEstimator, mut monitor: crate::ln::channelmonitor::ManyChannelMonitor, mut tx_broadcaster: crate::chain::chaininterface::BroadcasterInterface, mut logger: crate::util::logger::Logger, mut keys_manager: crate::chain::keysinterface::KeysInterface, mut config: crate::util::config::UserConfig, mut current_blockchain_height: usize) -> ChannelManager {
|
||||
let mut ret = lightning::ln::channelmanager::ChannelManager::new(network.into_bitcoin(), fee_est, monitor, tx_broadcaster, logger, keys_manager, *unsafe { Box::from_raw(config.take_ptr()) }, current_blockchain_height);
|
||||
ChannelManager { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Creates a new outbound channel to the given remote node and with the given value.
|
||||
///
|
||||
/// user_id will be provided back as user_channel_id in FundingGenerationReady and
|
||||
/// FundingBroadcastSafe events to allow tracking of which events correspond with which
|
||||
/// create_channel call. Note that user_channel_id defaults to 0 for inbound channels, so you
|
||||
/// may wish to avoid using 0 for user_id here.
|
||||
///
|
||||
/// If successful, will generate a SendOpenChannel message event, so you should probably poll
|
||||
/// PeerManager::process_events afterwards.
|
||||
///
|
||||
/// Raises APIError::APIMisuseError when channel_value_satoshis > 2**24 or push_msat is
|
||||
/// greater than channel_value_satoshis * 1k or channel_value_satoshis is < 1000.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_create_channel(this_arg: &ChannelManager, mut their_network_key: crate::c_types::PublicKey, mut channel_value_satoshis: u64, mut push_msat: u64, mut user_id: u64, mut override_config: crate::util::config::UserConfig) -> crate::c_types::derived::CResult_NoneAPIErrorZ {
|
||||
let mut local_override_config = if override_config.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(override_config.take_ptr()) } }) };
|
||||
let mut ret = unsafe { &*this_arg.inner }.create_channel(their_network_key.into_rust(), channel_value_satoshis, push_msat, user_id, local_override_config);
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::util::errors::APIError::native_into(e) }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Gets the list of open channels, in random order. See ChannelDetail field documentation for
|
||||
/// more information.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_list_channels(this_arg: &ChannelManager) -> crate::c_types::derived::CVec_ChannelDetailsZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.list_channels();
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::ln::channelmanager::ChannelDetails { inner: Box::into_raw(Box::new(item)), is_owned: true } }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
/// Gets the list of usable channels, in random order. Useful as an argument to
|
||||
/// get_route to ensure non-announced channels are used.
|
||||
///
|
||||
/// These are guaranteed to have their is_live value set to true, see the documentation for
|
||||
/// ChannelDetails::is_live for more info on exactly what the criteria are.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_list_usable_channels(this_arg: &ChannelManager) -> crate::c_types::derived::CVec_ChannelDetailsZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.list_usable_channels();
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::ln::channelmanager::ChannelDetails { inner: Box::into_raw(Box::new(item)), is_owned: true } }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
/// Begins the process of closing a channel. After this call (plus some timeout), no new HTLCs
|
||||
/// will be accepted on the given channel, and after additional timeout/the closing of all
|
||||
/// pending HTLCs, the channel will be closed on chain.
|
||||
///
|
||||
/// May generate a SendShutdown message event on success, which should be relayed.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_close_channel(this_arg: &ChannelManager, channel_id: *const [u8; 32]) -> crate::c_types::derived::CResult_NoneAPIErrorZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.close_channel(unsafe { &*channel_id});
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::util::errors::APIError::native_into(e) }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Force closes a channel, immediately broadcasting the latest local commitment transaction to
|
||||
/// the chain and rejecting new HTLCs on the given channel.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_force_close_channel(this_arg: &ChannelManager, channel_id: *const [u8; 32]) {
|
||||
unsafe { &*this_arg.inner }.force_close_channel(unsafe { &*channel_id})
|
||||
}
|
||||
|
||||
/// Force close all channels, immediately broadcasting the latest local commitment transaction
|
||||
/// for each to the chain and rejecting new HTLCs on each.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_force_close_all_channels(this_arg: &ChannelManager) {
|
||||
unsafe { &*this_arg.inner }.force_close_all_channels()
|
||||
}
|
||||
|
||||
/// Sends a payment along a given route.
|
||||
///
|
||||
/// Value parameters are provided via the last hop in route, see documentation for RouteHop
|
||||
/// fields for more info.
|
||||
///
|
||||
/// Note that if the payment_hash already exists elsewhere (eg you're sending a duplicative
|
||||
/// payment), we don't do anything to stop you! We always try to ensure that if the provided
|
||||
/// next hop knows the preimage to payment_hash they can claim an additional amount as
|
||||
/// specified in the last hop in the route! Thus, you should probably do your own
|
||||
/// payment_preimage tracking (which you should already be doing as they represent \"proof of
|
||||
/// payment\") and prevent double-sends yourself.
|
||||
///
|
||||
/// May generate SendHTLCs message(s) event on success, which should be relayed.
|
||||
///
|
||||
/// Each path may have a different return value, and PaymentSendValue may return a Vec with
|
||||
/// each entry matching the corresponding-index entry in the route paths, see
|
||||
/// PaymentSendFailure for more info.
|
||||
///
|
||||
/// In general, a path may raise:
|
||||
/// * APIError::RouteError when an invalid route or forwarding parameter (cltv_delta, fee,
|
||||
/// node public key) is specified.
|
||||
/// * APIError::ChannelUnavailable if the next-hop channel is not available for updates
|
||||
/// (including due to previous monitor update failure or new permanent monitor update
|
||||
/// failure).
|
||||
/// * APIError::MonitorUpdateFailed if a new monitor update failure prevented sending the
|
||||
/// relevant updates.
|
||||
///
|
||||
/// Note that depending on the type of the PaymentSendFailure the HTLC may have been
|
||||
/// irrevocably committed to on our end. In such a case, do NOT retry the payment with a
|
||||
/// different route unless you intend to pay twice!
|
||||
///
|
||||
/// payment_secret is unrelated to payment_hash (or PaymentPreimage) and exists to authenticate
|
||||
/// the sender to the recipient and prevent payment-probing (deanonymization) attacks. For
|
||||
/// newer nodes, it will be provided to you in the invoice. If you do not have one, the Route
|
||||
/// must not contain multiple paths as multi-path payments require a recipient-provided
|
||||
/// payment_secret.
|
||||
/// If a payment_secret *is* provided, we assume that the invoice had the payment_secret feature
|
||||
/// bit set (either as required or as available). If multiple paths are present in the Route,
|
||||
/// we assume the invoice had the basic_mpp feature set.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_send_payment(this_arg: &ChannelManager, route: &crate::routing::router::Route, mut payment_hash: crate::c_types::ThirtyTwoBytes, payment_secret: crate::c_types::ThirtyTwoBytes) -> crate::c_types::derived::CResult_NonePaymentSendFailureZ {
|
||||
let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret.data) }) };
|
||||
let mut ret = unsafe { &*this_arg.inner }.send_payment(unsafe { &*route.inner }, ::lightning::ln::channelmanager::PaymentHash(payment_hash.data), &local_payment_secret);
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::channelmanager::PaymentSendFailure { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Call this upon creation of a funding transaction for the given channel.
|
||||
///
|
||||
/// Note that ALL inputs in the transaction pointed to by funding_txo MUST spend SegWit outputs
|
||||
/// or your counterparty can steal your funds!
|
||||
///
|
||||
/// Panics if a funding transaction has already been provided for this channel.
|
||||
///
|
||||
/// May panic if the funding_txo is duplicative with some other channel (note that this should
|
||||
/// be trivially prevented by using unique funding transaction keys per-channel).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_funding_transaction_generated(this_arg: &ChannelManager, temporary_channel_id: *const [u8; 32], mut funding_txo: crate::chain::transaction::OutPoint) {
|
||||
unsafe { &*this_arg.inner }.funding_transaction_generated(unsafe { &*temporary_channel_id}, *unsafe { Box::from_raw(funding_txo.take_ptr()) })
|
||||
}
|
||||
|
||||
/// Generates a signed node_announcement from the given arguments and creates a
|
||||
/// BroadcastNodeAnnouncement event. Note that such messages will be ignored unless peers have
|
||||
/// seen a channel_announcement from us (ie unless we have public channels open).
|
||||
///
|
||||
/// RGB is a node \"color\" and alias is a printable human-readable string to describe this node
|
||||
/// to humans. They carry no in-protocol meaning.
|
||||
///
|
||||
/// addresses represent the set (possibly empty) of socket addresses on which this node accepts
|
||||
/// incoming connections. These will be broadcast to the network, publicly tying these
|
||||
/// addresses together. If you wish to preserve user privacy, addresses should likely contain
|
||||
/// only Tor Onion addresses.
|
||||
///
|
||||
/// Panics if addresses is absurdly large (more than 500).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_broadcast_node_announcement(this_arg: &ChannelManager, mut rgb: crate::c_types::ThreeBytes, mut alias: crate::c_types::ThirtyTwoBytes, mut addresses: crate::c_types::derived::CVec_NetAddressZ) {
|
||||
let mut local_addresses = Vec::new(); for mut item in addresses.into_rust().drain(..) { local_addresses.push( { item.into_native() }); };
|
||||
unsafe { &*this_arg.inner }.broadcast_node_announcement(rgb.data, alias.data, local_addresses)
|
||||
}
|
||||
|
||||
/// Processes HTLCs which are pending waiting on random forward delay.
|
||||
///
|
||||
/// Should only really ever be called in response to a PendingHTLCsForwardable event.
|
||||
/// Will likely generate further events.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_process_pending_htlc_forwards(this_arg: &ChannelManager) {
|
||||
unsafe { &*this_arg.inner }.process_pending_htlc_forwards()
|
||||
}
|
||||
|
||||
/// If a peer is disconnected we mark any channels with that peer as 'disabled'.
|
||||
/// After some time, if channels are still disabled we need to broadcast a ChannelUpdate
|
||||
/// to inform the network about the uselessness of these channels.
|
||||
///
|
||||
/// This method handles all the details, and must be called roughly once per minute.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_timer_chan_freshness_every_min(this_arg: &ChannelManager) {
|
||||
unsafe { &*this_arg.inner }.timer_chan_freshness_every_min()
|
||||
}
|
||||
|
||||
/// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect
|
||||
/// after a PaymentReceived event, failing the HTLC back to its origin and freeing resources
|
||||
/// along the path (including in our own channel on which we received it).
|
||||
/// Returns false if no payment was found to fail backwards, true if the process of failing the
|
||||
/// HTLC backwards has been started.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_fail_htlc_backwards(this_arg: &ChannelManager, payment_hash: *const [u8; 32], payment_secret: crate::c_types::ThirtyTwoBytes) -> bool {
|
||||
let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret.data) }) };
|
||||
let mut ret = unsafe { &*this_arg.inner }.fail_htlc_backwards(&::lightning::ln::channelmanager::PaymentHash(unsafe { *payment_hash }), &local_payment_secret);
|
||||
ret
|
||||
}
|
||||
|
||||
/// Provides a payment preimage in response to a PaymentReceived event, returning true and
|
||||
/// generating message events for the net layer to claim the payment, if possible. Thus, you
|
||||
/// should probably kick the net layer to go send messages if this returns true!
|
||||
///
|
||||
/// You must specify the expected amounts for this HTLC, and we will only claim HTLCs
|
||||
/// available within a few percent of the expected amount. This is critical for several
|
||||
/// reasons : a) it avoids providing senders with `proof-of-payment` (in the form of the
|
||||
/// payment_preimage without having provided the full value and b) it avoids certain
|
||||
/// privacy-breaking recipient-probing attacks which may reveal payment activity to
|
||||
/// motivated attackers.
|
||||
///
|
||||
/// Note that the privacy concerns in (b) are not relevant in payments with a payment_secret
|
||||
/// set. Thus, for such payments we will claim any payments which do not under-pay.
|
||||
///
|
||||
/// May panic if called except in response to a PaymentReceived event.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_claim_funds(this_arg: &ChannelManager, mut payment_preimage: crate::c_types::ThirtyTwoBytes, payment_secret: crate::c_types::ThirtyTwoBytes, mut expected_amount: u64) -> bool {
|
||||
let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret.data) }) };
|
||||
let mut ret = unsafe { &*this_arg.inner }.claim_funds(::lightning::ln::channelmanager::PaymentPreimage(payment_preimage.data), &local_payment_secret, expected_amount);
|
||||
ret
|
||||
}
|
||||
|
||||
/// Gets the node_id held by this ChannelManager
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_get_our_node_id(this_arg: &ChannelManager) -> crate::c_types::PublicKey {
|
||||
let mut ret = unsafe { &*this_arg.inner }.get_our_node_id();
|
||||
crate::c_types::PublicKey::from_rust(&ret)
|
||||
}
|
||||
|
||||
/// Restores a single, given channel to normal operation after a
|
||||
/// ChannelMonitorUpdateErr::TemporaryFailure was returned from a channel monitor update
|
||||
/// operation.
|
||||
///
|
||||
/// All ChannelMonitor updates up to and including highest_applied_update_id must have been
|
||||
/// fully committed in every copy of the given channels' ChannelMonitors.
|
||||
///
|
||||
/// Note that there is no effect to calling with a highest_applied_update_id other than the
|
||||
/// current latest ChannelMonitorUpdate and one call to this function after multiple
|
||||
/// ChannelMonitorUpdateErr::TemporaryFailures is fine. The highest_applied_update_id field
|
||||
/// exists largely only to prevent races between this and concurrent update_monitor calls.
|
||||
///
|
||||
/// Thus, the anticipated use is, at a high level:
|
||||
/// 1) You register a ManyChannelMonitor with this ChannelManager,
|
||||
/// 2) it stores each update to disk, and begins updating any remote (eg watchtower) copies of
|
||||
/// said ChannelMonitors as it can, returning ChannelMonitorUpdateErr::TemporaryFailures
|
||||
/// any time it cannot do so instantly,
|
||||
/// 3) update(s) are applied to each remote copy of a ChannelMonitor,
|
||||
/// 4) once all remote copies are updated, you call this function with the update_id that
|
||||
/// completed, and once it is the latest the Channel will be re-enabled.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_channel_monitor_updated(this_arg: &ChannelManager, funding_txo: &crate::chain::transaction::OutPoint, mut highest_applied_update_id: u64) {
|
||||
unsafe { &*this_arg.inner }.channel_monitor_updated(unsafe { &*funding_txo.inner }, highest_applied_update_id)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_as_MessageSendEventsProvider(this_arg: *const ChannelManager) -> crate::util::events::MessageSendEventsProvider {
|
||||
crate::util::events::MessageSendEventsProvider {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
get_and_clear_pending_msg_events: ChannelManager_MessageSendEventsProvider_get_and_clear_pending_msg_events,
|
||||
}
|
||||
}
|
||||
use lightning::util::events::MessageSendEventsProvider as MessageSendEventsProviderTraitImport;
|
||||
#[must_use]
|
||||
extern "C" fn ChannelManager_MessageSendEventsProvider_get_and_clear_pending_msg_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_MessageSendEventZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeChannelManager) }.get_and_clear_pending_msg_events();
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::util::events::MessageSendEvent::native_into(item) }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_as_EventsProvider(this_arg: *const ChannelManager) -> crate::util::events::EventsProvider {
|
||||
crate::util::events::EventsProvider {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
get_and_clear_pending_events: ChannelManager_EventsProvider_get_and_clear_pending_events,
|
||||
}
|
||||
}
|
||||
use lightning::util::events::EventsProvider as EventsProviderTraitImport;
|
||||
#[must_use]
|
||||
extern "C" fn ChannelManager_EventsProvider_get_and_clear_pending_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_EventZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeChannelManager) }.get_and_clear_pending_events();
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::util::events::Event::native_into(item) }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_as_ChainListener(this_arg: *const ChannelManager) -> crate::chain::chaininterface::ChainListener {
|
||||
crate::chain::chaininterface::ChainListener {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
block_connected: ChannelManager_ChainListener_block_connected,
|
||||
block_disconnected: ChannelManager_ChainListener_block_disconnected,
|
||||
}
|
||||
}
|
||||
use lightning::chain::chaininterface::ChainListener as ChainListenerTraitImport;
|
||||
extern "C" fn ChannelManager_ChainListener_block_connected(this_arg: *const c_void, header: *const [u8; 80], mut height: u32, mut txn_matched: crate::c_types::derived::CVec_TransactionZ, mut indexes_of_txn_matched: crate::c_types::usizeslice) {
|
||||
let mut local_txn_matched = Vec::new(); for mut item in txn_matched.into_rust().drain(..) { local_txn_matched.push( { ::bitcoin::consensus::encode::deserialize(&item.into_rust()[..]).unwrap() }); };
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.block_connected(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), height, &local_txn_matched.iter().collect::<Vec<_>>()[..], indexes_of_txn_matched.to_slice())
|
||||
}
|
||||
extern "C" fn ChannelManager_ChainListener_block_disconnected(this_arg: *const c_void, header: *const [u8; 80], unused_0: u32) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.block_disconnected(&::bitcoin::consensus::encode::deserialize(unsafe { &*header }).unwrap(), unused_0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManager_as_ChannelMessageHandler(this_arg: *const ChannelManager) -> crate::ln::msgs::ChannelMessageHandler {
|
||||
crate::ln::msgs::ChannelMessageHandler {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
handle_open_channel: ChannelManager_ChannelMessageHandler_handle_open_channel,
|
||||
handle_accept_channel: ChannelManager_ChannelMessageHandler_handle_accept_channel,
|
||||
handle_funding_created: ChannelManager_ChannelMessageHandler_handle_funding_created,
|
||||
handle_funding_signed: ChannelManager_ChannelMessageHandler_handle_funding_signed,
|
||||
handle_funding_locked: ChannelManager_ChannelMessageHandler_handle_funding_locked,
|
||||
handle_shutdown: ChannelManager_ChannelMessageHandler_handle_shutdown,
|
||||
handle_closing_signed: ChannelManager_ChannelMessageHandler_handle_closing_signed,
|
||||
handle_update_add_htlc: ChannelManager_ChannelMessageHandler_handle_update_add_htlc,
|
||||
handle_update_fulfill_htlc: ChannelManager_ChannelMessageHandler_handle_update_fulfill_htlc,
|
||||
handle_update_fail_htlc: ChannelManager_ChannelMessageHandler_handle_update_fail_htlc,
|
||||
handle_update_fail_malformed_htlc: ChannelManager_ChannelMessageHandler_handle_update_fail_malformed_htlc,
|
||||
handle_commitment_signed: ChannelManager_ChannelMessageHandler_handle_commitment_signed,
|
||||
handle_revoke_and_ack: ChannelManager_ChannelMessageHandler_handle_revoke_and_ack,
|
||||
handle_update_fee: ChannelManager_ChannelMessageHandler_handle_update_fee,
|
||||
handle_announcement_signatures: ChannelManager_ChannelMessageHandler_handle_announcement_signatures,
|
||||
peer_disconnected: ChannelManager_ChannelMessageHandler_peer_disconnected,
|
||||
peer_connected: ChannelManager_ChannelMessageHandler_peer_connected,
|
||||
handle_channel_reestablish: ChannelManager_ChannelMessageHandler_handle_channel_reestablish,
|
||||
handle_error: ChannelManager_ChannelMessageHandler_handle_error,
|
||||
MessageSendEventsProvider: crate::util::events::MessageSendEventsProvider {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
get_and_clear_pending_msg_events: ChannelManager_ChannelMessageHandler_get_and_clear_pending_msg_events,
|
||||
},
|
||||
}
|
||||
}
|
||||
use lightning::ln::msgs::ChannelMessageHandler as ChannelMessageHandlerTraitImport;
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_open_channel(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, mut their_features: crate::ln::features::InitFeatures, msg: &crate::ln::msgs::OpenChannel) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_open_channel(&their_node_id.into_rust(), *unsafe { Box::from_raw(their_features.take_ptr()) }, unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_accept_channel(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, mut their_features: crate::ln::features::InitFeatures, msg: &crate::ln::msgs::AcceptChannel) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_accept_channel(&their_node_id.into_rust(), *unsafe { Box::from_raw(their_features.take_ptr()) }, unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_funding_created(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::FundingCreated) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_funding_created(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_funding_signed(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::FundingSigned) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_funding_signed(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_funding_locked(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::FundingLocked) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_funding_locked(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_shutdown(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::Shutdown) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_shutdown(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_closing_signed(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::ClosingSigned) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_closing_signed(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_update_add_htlc(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::UpdateAddHTLC) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_update_add_htlc(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_update_fulfill_htlc(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::UpdateFulfillHTLC) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_update_fulfill_htlc(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_update_fail_htlc(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::UpdateFailHTLC) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_update_fail_htlc(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_update_fail_malformed_htlc(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::UpdateFailMalformedHTLC) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_update_fail_malformed_htlc(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_commitment_signed(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::CommitmentSigned) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_commitment_signed(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_revoke_and_ack(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::RevokeAndACK) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_revoke_and_ack(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_update_fee(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::UpdateFee) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_update_fee(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_announcement_signatures(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::AnnouncementSignatures) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_announcement_signatures(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_channel_reestablish(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::ChannelReestablish) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_channel_reestablish(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_peer_disconnected(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, mut no_connection_possible: bool) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.peer_disconnected(&their_node_id.into_rust(), no_connection_possible)
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_peer_connected(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, init_msg: &crate::ln::msgs::Init) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.peer_connected(&their_node_id.into_rust(), unsafe { &*init_msg.inner })
|
||||
}
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_handle_error(this_arg: *const c_void, their_node_id: crate::c_types::PublicKey, msg: &crate::ln::msgs::ErrorMessage) {
|
||||
unsafe { &mut *(this_arg as *mut nativeChannelManager) }.handle_error(&their_node_id.into_rust(), unsafe { &*msg.inner })
|
||||
}
|
||||
use lightning::util::events::MessageSendEventsProvider as nativeMessageSendEventsProviderTrait;
|
||||
#[must_use]
|
||||
extern "C" fn ChannelManager_ChannelMessageHandler_get_and_clear_pending_msg_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_MessageSendEventZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeChannelManager) }.get_and_clear_pending_msg_events();
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::util::events::MessageSendEvent::native_into(item) }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
|
||||
use lightning::ln::channelmanager::ChannelManagerReadArgs as nativeChannelManagerReadArgsImport;
|
||||
type nativeChannelManagerReadArgs = nativeChannelManagerReadArgsImport<'static, crate::chain::keysinterface::ChannelKeys, crate::ln::channelmonitor::ManyChannelMonitor, crate::chain::chaininterface::BroadcasterInterface, crate::chain::keysinterface::KeysInterface, crate::chain::chaininterface::FeeEstimator, crate::util::logger::Logger>;
|
||||
|
||||
/// Arguments for the creation of a ChannelManager that are not deserialized.
|
||||
///
|
||||
/// At a high-level, the process for deserializing a ChannelManager and resuming normal operation
|
||||
/// is:
|
||||
/// 1) Deserialize all stored ChannelMonitors.
|
||||
/// 2) Deserialize the ChannelManager by filling in this struct and calling <(Sha256dHash,
|
||||
/// ChannelManager)>::read(reader, args).
|
||||
/// This may result in closing some Channels if the ChannelMonitor is newer than the stored
|
||||
/// ChannelManager state to ensure no loss of funds. Thus, transactions may be broadcasted.
|
||||
/// 3) Register all relevant ChannelMonitor outpoints with your chain watch mechanism using
|
||||
/// ChannelMonitor::get_monitored_outpoints and ChannelMonitor::get_funding_txo().
|
||||
/// 4) Reconnect blocks on your ChannelMonitors.
|
||||
/// 5) Move the ChannelMonitors into your local ManyChannelMonitor.
|
||||
/// 6) Disconnect/connect blocks on the ChannelManager.
|
||||
/// 7) Register the new ChannelManager with your ChainWatchInterface.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelManagerReadArgs {
|
||||
/// Nearly everyhwere, 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 nativeChannelManagerReadArgs,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelManagerReadArgs {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_free(this_ptr: ChannelManagerReadArgs) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelManagerReadArgs_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelManagerReadArgs); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelManagerReadArgs {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelManagerReadArgs {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// The keys provider which will give us relevant keys. Some keys will be loaded during
|
||||
/// deserialization.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_get_keys_manager(this_ptr: &ChannelManagerReadArgs) -> *const crate::chain::keysinterface::KeysInterface {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.keys_manager;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// The keys provider which will give us relevant keys. Some keys will be loaded during
|
||||
/// deserialization.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_set_keys_manager(this_ptr: &mut ChannelManagerReadArgs, mut val: crate::chain::keysinterface::KeysInterface) {
|
||||
unsafe { &mut *this_ptr.inner }.keys_manager = val;
|
||||
}
|
||||
/// The fee_estimator for use in the ChannelManager in the future.
|
||||
///
|
||||
/// No calls to the FeeEstimator will be made during deserialization.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_get_fee_estimator(this_ptr: &ChannelManagerReadArgs) -> *const crate::chain::chaininterface::FeeEstimator {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.fee_estimator;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// The fee_estimator for use in the ChannelManager in the future.
|
||||
///
|
||||
/// No calls to the FeeEstimator will be made during deserialization.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_set_fee_estimator(this_ptr: &mut ChannelManagerReadArgs, mut val: crate::chain::chaininterface::FeeEstimator) {
|
||||
unsafe { &mut *this_ptr.inner }.fee_estimator = val;
|
||||
}
|
||||
/// The ManyChannelMonitor for use in the ChannelManager in the future.
|
||||
///
|
||||
/// No calls to the ManyChannelMonitor will be made during deserialization. It is assumed that
|
||||
/// you have deserialized ChannelMonitors separately and will add them to your
|
||||
/// ManyChannelMonitor after deserializing this ChannelManager.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_get_monitor(this_ptr: &ChannelManagerReadArgs) -> *const crate::ln::channelmonitor::ManyChannelMonitor {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.monitor;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// The ManyChannelMonitor for use in the ChannelManager in the future.
|
||||
///
|
||||
/// No calls to the ManyChannelMonitor will be made during deserialization. It is assumed that
|
||||
/// you have deserialized ChannelMonitors separately and will add them to your
|
||||
/// ManyChannelMonitor after deserializing this ChannelManager.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_set_monitor(this_ptr: &mut ChannelManagerReadArgs, mut val: crate::ln::channelmonitor::ManyChannelMonitor) {
|
||||
unsafe { &mut *this_ptr.inner }.monitor = val;
|
||||
}
|
||||
/// The BroadcasterInterface which will be used in the ChannelManager in the future and may be
|
||||
/// used to broadcast the latest local commitment transactions of channels which must be
|
||||
/// force-closed during deserialization.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_get_tx_broadcaster(this_ptr: &ChannelManagerReadArgs) -> *const crate::chain::chaininterface::BroadcasterInterface {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.tx_broadcaster;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// The BroadcasterInterface which will be used in the ChannelManager in the future and may be
|
||||
/// used to broadcast the latest local commitment transactions of channels which must be
|
||||
/// force-closed during deserialization.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_set_tx_broadcaster(this_ptr: &mut ChannelManagerReadArgs, mut val: crate::chain::chaininterface::BroadcasterInterface) {
|
||||
unsafe { &mut *this_ptr.inner }.tx_broadcaster = val;
|
||||
}
|
||||
/// The Logger for use in the ChannelManager and which may be used to log information during
|
||||
/// deserialization.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_get_logger(this_ptr: &ChannelManagerReadArgs) -> *const crate::util::logger::Logger {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.logger;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// The Logger for use in the ChannelManager and which may be used to log information during
|
||||
/// deserialization.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_set_logger(this_ptr: &mut ChannelManagerReadArgs, mut val: crate::util::logger::Logger) {
|
||||
unsafe { &mut *this_ptr.inner }.logger = val;
|
||||
}
|
||||
/// Default settings used for new channels. Any existing channels will continue to use the
|
||||
/// runtime settings which were stored when the ChannelManager was serialized.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_get_default_config(this_ptr: &ChannelManagerReadArgs) -> crate::util::config::UserConfig {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.default_config;
|
||||
crate::util::config::UserConfig { inner: unsafe { ( (&((*inner_val)) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
/// Default settings used for new channels. Any existing channels will continue to use the
|
||||
/// runtime settings which were stored when the ChannelManager was serialized.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_set_default_config(this_ptr: &mut ChannelManagerReadArgs, mut val: crate::util::config::UserConfig) {
|
||||
unsafe { &mut *this_ptr.inner }.default_config = *unsafe { Box::from_raw(val.take_ptr()) };
|
||||
}
|
||||
/// Simple utility function to create a ChannelManagerReadArgs which creates the monitor
|
||||
/// HashMap for you. This is primarily useful for C bindings where it is not practical to
|
||||
/// populate a HashMap directly from C.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelManagerReadArgs_new(mut keys_manager: crate::chain::keysinterface::KeysInterface, mut fee_estimator: crate::chain::chaininterface::FeeEstimator, mut monitor: crate::ln::channelmonitor::ManyChannelMonitor, mut tx_broadcaster: crate::chain::chaininterface::BroadcasterInterface, mut logger: crate::util::logger::Logger, mut default_config: crate::util::config::UserConfig, mut channel_monitors: crate::c_types::derived::CVec_ChannelMonitorZ) -> ChannelManagerReadArgs {
|
||||
let mut local_channel_monitors = Vec::new(); for mut item in channel_monitors.into_rust().drain(..) { local_channel_monitors.push( { unsafe { &mut *item.inner } }); };
|
||||
let mut ret = lightning::ln::channelmanager::ChannelManagerReadArgs::new(keys_manager, fee_estimator, monitor, tx_broadcaster, logger, *unsafe { Box::from_raw(default_config.take_ptr()) }, local_channel_monitors);
|
||||
ChannelManagerReadArgs { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
550
lightning-c-bindings/src/ln/channelmonitor.rs
Normal file
550
lightning-c-bindings/src/ln/channelmonitor.rs
Normal file
|
@ -0,0 +1,550 @@
|
|||
//! The logic to monitor for on-chain transactions and create the relevant claim responses lives
|
||||
//! here.
|
||||
//!
|
||||
//! ChannelMonitor objects are generated by ChannelManager in response to relevant
|
||||
//! messages/actions, and MUST be persisted to disk (and, preferably, remotely) before progress can
|
||||
//! be made in responding to certain messages, see ManyChannelMonitor for more.
|
||||
//!
|
||||
//! Note that ChannelMonitors are an important part of the lightning trust model and a copy of the
|
||||
//! latest ChannelMonitor must always be actively monitoring for chain updates (and no out-of-date
|
||||
//! ChannelMonitors should do so). Thus, if you're building rust-lightning into an HSM or other
|
||||
//! security-domain-separated system design, you should consider having multiple paths for
|
||||
//! ChannelMonitors to get out of the HSM and onto monitoring devices.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
|
||||
use lightning::ln::channelmonitor::ChannelMonitorUpdate as nativeChannelMonitorUpdateImport;
|
||||
type nativeChannelMonitorUpdate = nativeChannelMonitorUpdateImport;
|
||||
|
||||
/// An update generated by the underlying Channel itself which contains some new information the
|
||||
/// ChannelMonitor should be made aware of.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelMonitorUpdate {
|
||||
/// Nearly everyhwere, 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 nativeChannelMonitorUpdate,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelMonitorUpdate {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitorUpdate_free(this_ptr: ChannelMonitorUpdate) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelMonitorUpdate_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelMonitorUpdate); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelMonitorUpdate {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelMonitorUpdate {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for ChannelMonitorUpdate {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn ChannelMonitorUpdate_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelMonitorUpdate)).clone() })) as *mut c_void
|
||||
}
|
||||
/// The sequence number of this update. Updates *must* be replayed in-order according to this
|
||||
/// sequence number (and updates may panic if they are not). The update_id values are strictly
|
||||
/// increasing and increase by one for each new update.
|
||||
///
|
||||
/// This sequence number is also used to track up to which points updates which returned
|
||||
/// ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
|
||||
/// ChannelMonitor when ChannelManager::channel_monitor_updated is called.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitorUpdate_get_update_id(this_ptr: &ChannelMonitorUpdate) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.update_id;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The sequence number of this update. Updates *must* be replayed in-order according to this
|
||||
/// sequence number (and updates may panic if they are not). The update_id values are strictly
|
||||
/// increasing and increase by one for each new update.
|
||||
///
|
||||
/// This sequence number is also used to track up to which points updates which returned
|
||||
/// ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
|
||||
/// ChannelMonitor when ChannelManager::channel_monitor_updated is called.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitorUpdate_set_update_id(this_ptr: &mut ChannelMonitorUpdate, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.update_id = val;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitorUpdate_write(obj: *const ChannelMonitorUpdate) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> ChannelMonitorUpdate {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
ChannelMonitorUpdate { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
ChannelMonitorUpdate { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
/// An error enum representing a failure to persist a channel monitor update.
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub enum ChannelMonitorUpdateErr {
|
||||
/// Used to indicate a temporary failure (eg connection to a watchtower or remote backup of
|
||||
/// our state failed, but is expected to succeed at some point in the future).
|
||||
///
|
||||
/// Such a failure will \"freeze\" a channel, preventing us from revoking old states or
|
||||
/// submitting new commitment transactions to the remote party. Once the update(s) which failed
|
||||
/// have been successfully applied, ChannelManager::channel_monitor_updated can be used to
|
||||
/// restore the channel to an operational state.
|
||||
///
|
||||
/// Note that a given ChannelManager will *never* re-generate a given ChannelMonitorUpdate. If
|
||||
/// you return a TemporaryFailure you must ensure that it is written to disk safely before
|
||||
/// writing out the latest ChannelManager state.
|
||||
///
|
||||
/// Even when a channel has been \"frozen\" updates to the ChannelMonitor can continue to occur
|
||||
/// (eg if an inbound HTLC which we forwarded was claimed upstream resulting in us attempting
|
||||
/// to claim it on this channel) and those updates must be applied wherever they can be. At
|
||||
/// least one such updated ChannelMonitor must be persisted otherwise PermanentFailure should
|
||||
/// be returned to get things on-chain ASAP using only the in-memory copy. Obviously updates to
|
||||
/// the channel which would invalidate previous ChannelMonitors are not made when a channel has
|
||||
/// been \"frozen\".
|
||||
///
|
||||
/// Note that even if updates made after TemporaryFailure succeed you must still call
|
||||
/// channel_monitor_updated to ensure you have the latest monitor and re-enable normal channel
|
||||
/// operation.
|
||||
///
|
||||
/// Note that the update being processed here will not be replayed for you when you call
|
||||
/// ChannelManager::channel_monitor_updated, so you must store the update itself along
|
||||
/// with the persisted ChannelMonitor on your own local disk prior to returning a
|
||||
/// TemporaryFailure. You may, of course, employ a journaling approach, storing only the
|
||||
/// ChannelMonitorUpdate on disk without updating the monitor itself, replaying the journal at
|
||||
/// reload-time.
|
||||
///
|
||||
/// For deployments where a copy of ChannelMonitors and other local state are backed up in a
|
||||
/// remote location (with local copies persisted immediately), it is anticipated that all
|
||||
/// updates will return TemporaryFailure until the remote copies could be updated.
|
||||
TemporaryFailure,
|
||||
/// Used to indicate no further channel monitor updates will be allowed (eg we've moved on to a
|
||||
/// different watchtower and cannot update with all watchtowers that were previously informed
|
||||
/// of this channel). This will force-close the channel in question (which will generate one
|
||||
/// final ChannelMonitorUpdate which must be delivered to at least one ChannelMonitor copy).
|
||||
///
|
||||
/// Should also be used to indicate a failure to update the local persisted copy of the channel
|
||||
/// monitor.
|
||||
PermanentFailure,
|
||||
}
|
||||
use lightning::ln::channelmonitor::ChannelMonitorUpdateErr as nativeChannelMonitorUpdateErr;
|
||||
impl ChannelMonitorUpdateErr {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn to_native(&self) -> nativeChannelMonitorUpdateErr {
|
||||
match self {
|
||||
ChannelMonitorUpdateErr::TemporaryFailure => nativeChannelMonitorUpdateErr::TemporaryFailure,
|
||||
ChannelMonitorUpdateErr::PermanentFailure => nativeChannelMonitorUpdateErr::PermanentFailure,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn into_native(self) -> nativeChannelMonitorUpdateErr {
|
||||
match self {
|
||||
ChannelMonitorUpdateErr::TemporaryFailure => nativeChannelMonitorUpdateErr::TemporaryFailure,
|
||||
ChannelMonitorUpdateErr::PermanentFailure => nativeChannelMonitorUpdateErr::PermanentFailure,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn from_native(native: &nativeChannelMonitorUpdateErr) -> Self {
|
||||
match native {
|
||||
nativeChannelMonitorUpdateErr::TemporaryFailure => ChannelMonitorUpdateErr::TemporaryFailure,
|
||||
nativeChannelMonitorUpdateErr::PermanentFailure => ChannelMonitorUpdateErr::PermanentFailure,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn native_into(native: nativeChannelMonitorUpdateErr) -> Self {
|
||||
match native {
|
||||
nativeChannelMonitorUpdateErr::TemporaryFailure => ChannelMonitorUpdateErr::TemporaryFailure,
|
||||
nativeChannelMonitorUpdateErr::PermanentFailure => ChannelMonitorUpdateErr::PermanentFailure,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::channelmonitor::MonitorUpdateError as nativeMonitorUpdateErrorImport;
|
||||
type nativeMonitorUpdateError = nativeMonitorUpdateErrorImport;
|
||||
|
||||
/// General Err type for ChannelMonitor actions. Generally, this implies that the data provided is
|
||||
/// inconsistent with the ChannelMonitor being called. eg for ChannelMonitor::update_monitor this
|
||||
/// means you tried to update a monitor for a different channel or the ChannelMonitorUpdate was
|
||||
/// corrupted.
|
||||
/// Contains a human-readable error message.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct MonitorUpdateError {
|
||||
/// Nearly everyhwere, 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 nativeMonitorUpdateError,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for MonitorUpdateError {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MonitorUpdateError_free(this_ptr: MonitorUpdateError) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn MonitorUpdateError_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeMonitorUpdateError); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl MonitorUpdateError {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeMonitorUpdateError {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::channelmonitor::MonitorEvent as nativeMonitorEventImport;
|
||||
type nativeMonitorEvent = nativeMonitorEventImport;
|
||||
|
||||
/// An event to be processed by the ChannelManager.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct MonitorEvent {
|
||||
/// Nearly everyhwere, 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 nativeMonitorEvent,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for MonitorEvent {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MonitorEvent_free(this_ptr: MonitorEvent) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn MonitorEvent_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeMonitorEvent); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl MonitorEvent {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeMonitorEvent {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::channelmonitor::HTLCUpdate as nativeHTLCUpdateImport;
|
||||
type nativeHTLCUpdate = nativeHTLCUpdateImport;
|
||||
|
||||
/// Simple structure send back by ManyChannelMonitor in case of HTLC detected onchain from a
|
||||
/// forward channel and from which info are needed to update HTLC in a backward channel.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct HTLCUpdate {
|
||||
/// Nearly everyhwere, 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 nativeHTLCUpdate,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for HTLCUpdate {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCUpdate_free(this_ptr: HTLCUpdate) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn HTLCUpdate_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeHTLCUpdate); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl HTLCUpdate {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeHTLCUpdate {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for HTLCUpdate {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn HTLCUpdate_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeHTLCUpdate)).clone() })) as *mut c_void
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCUpdate_write(obj: *const HTLCUpdate) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn HTLCUpdate_read(ser: crate::c_types::u8slice) -> HTLCUpdate {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
HTLCUpdate { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
HTLCUpdate { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::channelmonitor::ChannelMonitor as nativeChannelMonitorImport;
|
||||
type nativeChannelMonitor = nativeChannelMonitorImport<crate::chain::keysinterface::ChannelKeys>;
|
||||
|
||||
/// A ChannelMonitor handles chain events (blocks connected and disconnected) and generates
|
||||
/// on-chain transactions to ensure no loss of funds occurs.
|
||||
///
|
||||
/// You MUST ensure that no ChannelMonitors for a given channel anywhere contain out-of-date
|
||||
/// information and are actively monitoring the chain.
|
||||
///
|
||||
/// Pending Events or updated HTLCs which have not yet been read out by
|
||||
/// get_and_clear_pending_monitor_events or get_and_clear_pending_events are serialized to disk and
|
||||
/// reloaded at deserialize-time. Thus, you must ensure that, when handling events, all events
|
||||
/// gotten are fully handled before re-serializing the new state.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelMonitor {
|
||||
/// Nearly everyhwere, 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 nativeChannelMonitor,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelMonitor {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitor_free(this_ptr: ChannelMonitor) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelMonitor_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelMonitor); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelMonitor {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelMonitor {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Simple trait indicating ability to track a set of ChannelMonitors and multiplex events between
|
||||
/// them. Generally should be implemented by keeping a local SimpleManyChannelMonitor and passing
|
||||
/// events to it, while also taking any add/update_monitor events and passing them to some remote
|
||||
/// server(s).
|
||||
///
|
||||
/// In general, you must always have at least one local copy in memory, which must never fail to
|
||||
/// update (as it is responsible for broadcasting the latest state in case the channel is closed),
|
||||
/// and then persist it to various on-disk locations. If, for some reason, the in-memory copy fails
|
||||
/// to update (eg out-of-memory or some other condition), you must immediately shut down without
|
||||
/// taking any further action such as writing the current state to disk. This should likely be
|
||||
/// accomplished via panic!() or abort().
|
||||
///
|
||||
/// Note that any updates to a channel's monitor *must* be applied to each instance of the
|
||||
/// channel's monitor everywhere (including remote watchtowers) *before* this function returns. If
|
||||
/// an update occurs and a remote watchtower is left with old state, it may broadcast transactions
|
||||
/// which we have revoked, allowing our counterparty to claim all funds in the channel!
|
||||
///
|
||||
/// User needs to notify implementors of ManyChannelMonitor when a new block is connected or
|
||||
/// disconnected using their `block_connected` and `block_disconnected` methods. However, rather
|
||||
/// than calling these methods directly, the user should register implementors as listeners to the
|
||||
/// BlockNotifier and call the BlockNotifier's `block_(dis)connected` methods, which will notify
|
||||
/// all registered listeners in one go.
|
||||
#[repr(C)]
|
||||
pub struct ManyChannelMonitor {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Adds a monitor for the given `funding_txo`.
|
||||
///
|
||||
/// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
|
||||
/// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
|
||||
/// callbacks with the funding transaction, or any spends of it.
|
||||
///
|
||||
/// Further, the implementer must also ensure that each output returned in
|
||||
/// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
|
||||
/// any spends of any of the outputs.
|
||||
///
|
||||
/// Any spends of outputs which should have been registered which aren't passed to
|
||||
/// ChannelMonitors via block_connected may result in FUNDS LOSS.
|
||||
#[must_use]
|
||||
pub add_monitor: extern "C" fn (this_arg: *const c_void, funding_txo: crate::chain::transaction::OutPoint, monitor: crate::ln::channelmonitor::ChannelMonitor) -> crate::c_types::derived::CResult_NoneChannelMonitorUpdateErrZ,
|
||||
/// Updates a monitor for the given `funding_txo`.
|
||||
///
|
||||
/// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
|
||||
/// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
|
||||
/// callbacks with the funding transaction, or any spends of it.
|
||||
///
|
||||
/// Further, the implementer must also ensure that each output returned in
|
||||
/// monitor.get_watch_outputs() is registered to ensure that the provided monitor learns about
|
||||
/// any spends of any of the outputs.
|
||||
///
|
||||
/// Any spends of outputs which should have been registered which aren't passed to
|
||||
/// ChannelMonitors via block_connected may result in FUNDS LOSS.
|
||||
#[must_use]
|
||||
pub update_monitor: extern "C" fn (this_arg: *const c_void, funding_txo: crate::chain::transaction::OutPoint, monitor: crate::ln::channelmonitor::ChannelMonitorUpdate) -> crate::c_types::derived::CResult_NoneChannelMonitorUpdateErrZ,
|
||||
/// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
|
||||
/// with success or failure.
|
||||
///
|
||||
/// You should probably just call through to
|
||||
/// ChannelMonitor::get_and_clear_pending_monitor_events() for each ChannelMonitor and return
|
||||
/// the full list.
|
||||
#[must_use]
|
||||
pub get_and_clear_pending_monitor_events: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_MonitorEventZ,
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
unsafe impl Send for ManyChannelMonitor {}
|
||||
unsafe impl Sync for ManyChannelMonitor {}
|
||||
|
||||
use lightning::ln::channelmonitor::ManyChannelMonitor as rustManyChannelMonitor;
|
||||
impl rustManyChannelMonitor for ManyChannelMonitor {
|
||||
type Keys = crate::chain::keysinterface::ChannelKeys;
|
||||
fn add_monitor(&self, funding_txo: lightning::chain::transaction::OutPoint, monitor: lightning::ln::channelmonitor::ChannelMonitor<Self::Keys>) -> Result<(), lightning::ln::channelmonitor::ChannelMonitorUpdateErr> {
|
||||
let mut ret = (self.add_monitor)(self.this_arg, crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(funding_txo)), is_owned: true }, crate::ln::channelmonitor::ChannelMonitor { inner: Box::into_raw(Box::new(monitor)), is_owned: true });
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { () /*(*unsafe { Box::from_raw(ret.contents.result.take_ptr()) })*/ }), false => Err( { (*unsafe { Box::from_raw(ret.contents.err.take_ptr()) }).into_native() })};
|
||||
local_ret
|
||||
}
|
||||
fn update_monitor(&self, funding_txo: lightning::chain::transaction::OutPoint, monitor: lightning::ln::channelmonitor::ChannelMonitorUpdate) -> Result<(), lightning::ln::channelmonitor::ChannelMonitorUpdateErr> {
|
||||
let mut ret = (self.update_monitor)(self.this_arg, crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(funding_txo)), is_owned: true }, crate::ln::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(monitor)), is_owned: true });
|
||||
let mut local_ret = match ret.result_ok { true => Ok( { () /*(*unsafe { Box::from_raw(ret.contents.result.take_ptr()) })*/ }), false => Err( { (*unsafe { Box::from_raw(ret.contents.err.take_ptr()) }).into_native() })};
|
||||
local_ret
|
||||
}
|
||||
fn get_and_clear_pending_monitor_events(&self) -> Vec<lightning::ln::channelmonitor::MonitorEvent> {
|
||||
let mut ret = (self.get_and_clear_pending_monitor_events)(self.this_arg);
|
||||
let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { *unsafe { Box::from_raw(item.take_ptr()) } }); };
|
||||
local_ret
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for ManyChannelMonitor {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ManyChannelMonitor_free(this_ptr: ManyChannelMonitor) { }
|
||||
impl Drop for ManyChannelMonitor {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Updates a ChannelMonitor on the basis of some new information provided by the Channel
|
||||
/// itself.
|
||||
///
|
||||
/// panics if the given update is not the next update by update_id.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitor_update_monitor(this_arg: &mut ChannelMonitor, mut updates: crate::ln::channelmonitor::ChannelMonitorUpdate, broadcaster: &crate::chain::chaininterface::BroadcasterInterface, logger: &crate::util::logger::Logger) -> crate::c_types::derived::CResult_NoneMonitorUpdateErrorZ {
|
||||
let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.update_monitor(*unsafe { Box::from_raw(updates.take_ptr()) }, broadcaster, logger);
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::channelmonitor::MonitorUpdateError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Gets the update_id from the latest ChannelMonitorUpdate which was applied to this
|
||||
/// ChannelMonitor.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitor_get_latest_update_id(this_arg: &ChannelMonitor) -> u64 {
|
||||
let mut ret = unsafe { &*this_arg.inner }.get_latest_update_id();
|
||||
ret
|
||||
}
|
||||
|
||||
/// Gets the funding transaction outpoint of the channel this ChannelMonitor is monitoring for.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitor_get_funding_txo(this_arg: &ChannelMonitor) -> crate::c_types::derived::C2Tuple_OutPointScriptZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.get_funding_txo();
|
||||
let (ref orig_ret_0, ref orig_ret_1) = ret; let mut local_ret = (crate::chain::transaction::OutPoint { inner: unsafe { ( (&(*orig_ret_0) as *const _) as *mut _) }, is_owned: false }, orig_ret_1.clone().into_bytes().into()).into();
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Get the list of HTLCs who's status has been updated on chain. This should be called by
|
||||
/// ChannelManager via ManyChannelMonitor::get_and_clear_pending_monitor_events().
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitor_get_and_clear_pending_monitor_events(this_arg: &mut ChannelMonitor) -> crate::c_types::derived::CVec_MonitorEventZ {
|
||||
let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.get_and_clear_pending_monitor_events();
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::ln::channelmonitor::MonitorEvent { inner: Box::into_raw(Box::new(item)), is_owned: true } }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
/// Gets the list of pending events which were generated by previous actions, clearing the list
|
||||
/// in the process.
|
||||
///
|
||||
/// This is called by ManyChannelMonitor::get_and_clear_pending_events() and is equivalent to
|
||||
/// EventsProvider::get_and_clear_pending_events() except that it requires &mut self as we do
|
||||
/// no internal locking in ChannelMonitors.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitor_get_and_clear_pending_events(this_arg: &mut ChannelMonitor) -> crate::c_types::derived::CVec_EventZ {
|
||||
let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.get_and_clear_pending_events();
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::util::events::Event::native_into(item) }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
/// Used by ChannelManager deserialization to broadcast the latest local state if its copy of
|
||||
/// the Channel was out-of-date. You may use it to get a broadcastable local toxic tx in case of
|
||||
/// fallen-behind, i.e when receiving a channel_reestablish with a proof that our remote side knows
|
||||
/// a higher revocation secret than the local commitment number we are aware of. Broadcasting these
|
||||
/// transactions are UNSAFE, as they allow remote side to punish you. Nevertheless you may want to
|
||||
/// broadcast them if remote don't close channel with his higher commitment transaction after a
|
||||
/// substantial amount of time (a month or even a year) to get back funds. Best may be to contact
|
||||
/// out-of-band the other node operator to coordinate with him if option is available to you.
|
||||
/// In any-case, choice is up to the user.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelMonitor_get_latest_local_commitment_txn(this_arg: &mut ChannelMonitor, logger: &crate::util::logger::Logger) -> crate::c_types::derived::CVec_TransactionZ {
|
||||
let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.get_latest_local_commitment_txn(logger);
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { let mut local_ret_0 = ::bitcoin::consensus::encode::serialize(&item); local_ret_0.into() }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
136
lightning-c-bindings/src/ln/features.rs
Normal file
136
lightning-c-bindings/src/ln/features.rs
Normal file
|
@ -0,0 +1,136 @@
|
|||
//! Feature flag definitions for the Lightning protocol according to [BOLT #9].
|
||||
//!
|
||||
//! Lightning nodes advertise a supported set of operation through feature flags. Features are
|
||||
//! applicable for a specific context as indicated in some [messages]. [`Features`] encapsulates
|
||||
//! behavior for specifying and checking feature flags for a particular context. Each feature is
|
||||
//! defined internally by a trait specifying the corresponding flags (i.e., even and odd bits). A
|
||||
//! [`Context`] is used to parameterize [`Features`] and defines which features it can support.
|
||||
//!
|
||||
//! Whether a feature is considered \"known\" or \"unknown\" is relative to the implementation, whereas
|
||||
//! the term \"supports\" is used in reference to a particular set of [`Features`]. That is, a node
|
||||
//! supports a feature if it advertises the feature (as either required or optional) to its peers.
|
||||
//! And the implementation can interpret a feature if the feature is known to it.
|
||||
//!
|
||||
//! [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md
|
||||
//! [messages]: ../msgs/index.html
|
||||
//! [`Features`]: struct.Features.html
|
||||
//! [`Context`]: sealed/trait.Context.html
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
|
||||
use lightning::ln::features::InitFeatures as nativeInitFeaturesImport;
|
||||
type nativeInitFeatures = nativeInitFeaturesImport;
|
||||
|
||||
/// Features used within an `init` message.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct InitFeatures {
|
||||
/// Nearly everyhwere, 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 nativeInitFeatures,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for InitFeatures {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn InitFeatures_free(this_ptr: InitFeatures) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn InitFeatures_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeInitFeatures); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl InitFeatures {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeInitFeatures {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::features::NodeFeatures as nativeNodeFeaturesImport;
|
||||
type nativeNodeFeatures = nativeNodeFeaturesImport;
|
||||
|
||||
/// Features used within a `node_announcement` message.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct NodeFeatures {
|
||||
/// Nearly everyhwere, 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 nativeNodeFeatures,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for NodeFeatures {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeFeatures_free(this_ptr: NodeFeatures) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn NodeFeatures_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeNodeFeatures); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl NodeFeatures {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeNodeFeatures {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::features::ChannelFeatures as nativeChannelFeaturesImport;
|
||||
type nativeChannelFeatures = nativeChannelFeaturesImport;
|
||||
|
||||
/// Features used within a `channel_announcement` message.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelFeatures {
|
||||
/// Nearly everyhwere, 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 nativeChannelFeatures,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelFeatures {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelFeatures_free(this_ptr: ChannelFeatures) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelFeatures_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelFeatures); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelFeatures {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelFeatures {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
21
lightning-c-bindings/src/ln/mod.rs
Normal file
21
lightning-c-bindings/src/ln/mod.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
//! High level lightning structs and impls live here.
|
||||
//!
|
||||
//! You probably want to create a channelmanager::ChannelManager, and a routing::NetGraphMsgHandler first.
|
||||
//! Then, you probably want to pass them both on to a peer_handler::PeerManager and use that to
|
||||
//! create/manage connections and call get_and_clear_pending_events after each action, handling
|
||||
//! them appropriately.
|
||||
//!
|
||||
//! When you want to open/close a channel or send a payment, call into your ChannelManager and when
|
||||
//! you want to learn things about the network topology (eg get a route for sending a payment),
|
||||
//! call into your NetGraphMsgHandler.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
pub mod channelmanager;
|
||||
pub mod channelmonitor;
|
||||
pub mod msgs;
|
||||
pub mod peer_handler;
|
||||
pub mod chan_utils;
|
||||
pub mod features;
|
3867
lightning-c-bindings/src/ln/msgs.rs
Normal file
3867
lightning-c-bindings/src/ln/msgs.rs
Normal file
File diff suppressed because it is too large
Load diff
406
lightning-c-bindings/src/ln/peer_handler.rs
Normal file
406
lightning-c-bindings/src/ln/peer_handler.rs
Normal file
|
@ -0,0 +1,406 @@
|
|||
//! Top level peer message handling and socket handling logic lives here.
|
||||
//!
|
||||
//! Instead of actually servicing sockets ourselves we require that you implement the
|
||||
//! SocketDescriptor interface and use that to receive actions which you should perform on the
|
||||
//! socket, and call into PeerManager with bytes read from the socket. The PeerManager will then
|
||||
//! call into the provided message handlers (probably a ChannelManager and NetGraphmsgHandler) with messages
|
||||
//! they should handle, and encoding/sending response messages.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
|
||||
use lightning::ln::peer_handler::MessageHandler as nativeMessageHandlerImport;
|
||||
type nativeMessageHandler = nativeMessageHandlerImport<crate::ln::msgs::ChannelMessageHandler, crate::ln::msgs::RoutingMessageHandler>;
|
||||
|
||||
/// Provides references to trait impls which handle different types of messages.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct MessageHandler {
|
||||
/// Nearly everyhwere, 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 nativeMessageHandler,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for MessageHandler {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MessageHandler_free(this_ptr: MessageHandler) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn MessageHandler_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeMessageHandler); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl MessageHandler {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeMessageHandler {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// A message handler which handles messages specific to channels. Usually this is just a
|
||||
/// ChannelManager object.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MessageHandler_get_chan_handler(this_ptr: &MessageHandler) -> *const crate::ln::msgs::ChannelMessageHandler {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.chan_handler;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// A message handler which handles messages specific to channels. Usually this is just a
|
||||
/// ChannelManager object.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MessageHandler_set_chan_handler(this_ptr: &mut MessageHandler, mut val: crate::ln::msgs::ChannelMessageHandler) {
|
||||
unsafe { &mut *this_ptr.inner }.chan_handler = val;
|
||||
}
|
||||
/// A message handler which handles messages updating our knowledge of the network channel
|
||||
/// graph. Usually this is just a NetGraphMsgHandlerMonitor object.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MessageHandler_get_route_handler(this_ptr: &MessageHandler) -> *const crate::ln::msgs::RoutingMessageHandler {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.route_handler;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// A message handler which handles messages updating our knowledge of the network channel
|
||||
/// graph. Usually this is just a NetGraphMsgHandlerMonitor object.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MessageHandler_set_route_handler(this_ptr: &mut MessageHandler, mut val: crate::ln::msgs::RoutingMessageHandler) {
|
||||
unsafe { &mut *this_ptr.inner }.route_handler = val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MessageHandler_new(mut chan_handler_arg: crate::ln::msgs::ChannelMessageHandler, mut route_handler_arg: crate::ln::msgs::RoutingMessageHandler) -> MessageHandler {
|
||||
MessageHandler { inner: Box::into_raw(Box::new(nativeMessageHandler {
|
||||
chan_handler: chan_handler_arg,
|
||||
route_handler: route_handler_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
/// Provides an object which can be used to send data to and which uniquely identifies a connection
|
||||
/// to a remote host. You will need to be able to generate multiple of these which meet Eq and
|
||||
/// implement Hash to meet the PeerManager API.
|
||||
///
|
||||
/// For efficiency, Clone should be relatively cheap for this type.
|
||||
///
|
||||
/// You probably want to just extend an int and put a file descriptor in a struct and implement
|
||||
/// send_data. Note that if you are using a higher-level net library that may call close() itself,
|
||||
/// be careful to ensure you don't have races whereby you might register a new connection with an
|
||||
/// fd which is the same as a previous one which has yet to be removed via
|
||||
/// PeerManager::socket_disconnected().
|
||||
#[repr(C)]
|
||||
pub struct SocketDescriptor {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Attempts to send some data from the given slice to the peer.
|
||||
///
|
||||
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
|
||||
/// Note that in the disconnected case, socket_disconnected must still fire and further write
|
||||
/// attempts may occur until that time.
|
||||
///
|
||||
/// If the returned size is smaller than data.len(), a write_available event must
|
||||
/// trigger the next time more data can be written. Additionally, until the a send_data event
|
||||
/// completes fully, no further read_events should trigger on the same peer!
|
||||
///
|
||||
/// If a read_event on this descriptor had previously returned true (indicating that read
|
||||
/// events should be paused to prevent DoS in the send buffer), resume_read may be set
|
||||
/// indicating that read events on this descriptor should resume. A resume_read of false does
|
||||
/// *not* imply that further read events should be paused.
|
||||
#[must_use]
|
||||
pub send_data: extern "C" fn (this_arg: *mut c_void, data: crate::c_types::u8slice, resume_read: bool) -> usize,
|
||||
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
|
||||
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
|
||||
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
|
||||
/// though races may occur whereby disconnect_socket is called after a call to
|
||||
/// socket_disconnected but prior to socket_disconnected returning.
|
||||
pub disconnect_socket: extern "C" fn (this_arg: *mut c_void),
|
||||
pub eq: extern "C" fn (this_arg: *const c_void, other_arg: *const c_void) -> bool,
|
||||
pub hash: extern "C" fn (this_arg: *const c_void) -> u64,
|
||||
pub clone: Option<extern "C" fn (this_arg: *const c_void) -> *mut c_void>,
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
impl std::cmp::Eq for SocketDescriptor {}
|
||||
impl std::cmp::PartialEq for SocketDescriptor {
|
||||
fn eq(&self, o: &Self) -> bool { (self.eq)(self.this_arg, o.this_arg) }
|
||||
}
|
||||
impl std::hash::Hash for SocketDescriptor {
|
||||
fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) { hasher.write_u64((self.hash)(self.this_arg)) }
|
||||
}
|
||||
impl Clone for SocketDescriptor {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
this_arg: if let Some(f) = self.clone { (f)(self.this_arg) } else { self.this_arg },
|
||||
send_data: self.send_data.clone(),
|
||||
disconnect_socket: self.disconnect_socket.clone(),
|
||||
eq: self.eq.clone(),
|
||||
hash: self.hash.clone(),
|
||||
clone: self.clone.clone(),
|
||||
free: self.free.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::peer_handler::SocketDescriptor as rustSocketDescriptor;
|
||||
impl rustSocketDescriptor for SocketDescriptor {
|
||||
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize {
|
||||
let mut local_data = crate::c_types::u8slice::from_slice(data);
|
||||
let mut ret = (self.send_data)(self.this_arg, local_data, resume_read);
|
||||
ret
|
||||
}
|
||||
fn disconnect_socket(&mut self) {
|
||||
(self.disconnect_socket)(self.this_arg)
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for SocketDescriptor {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn SocketDescriptor_free(this_ptr: SocketDescriptor) { }
|
||||
impl Drop for SocketDescriptor {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::ln::peer_handler::PeerHandleError as nativePeerHandleErrorImport;
|
||||
type nativePeerHandleError = nativePeerHandleErrorImport;
|
||||
|
||||
/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
|
||||
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
|
||||
/// triggering a single socket_disconnected call (unless it was provided in response to a
|
||||
/// new_*_connection event, in which case no such socket_disconnected() must be called and the
|
||||
/// socket silently disconencted).
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct PeerHandleError {
|
||||
/// Nearly everyhwere, 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 nativePeerHandleError,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for PeerHandleError {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerHandleError_free(this_ptr: PeerHandleError) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn PeerHandleError_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativePeerHandleError); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl PeerHandleError {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativePeerHandleError {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Used to indicate that we probably can't make any future connections to this peer, implying
|
||||
/// we should go ahead and force-close any channels we have with it.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerHandleError_get_no_connection_possible(this_ptr: &PeerHandleError) -> bool {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.no_connection_possible;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Used to indicate that we probably can't make any future connections to this peer, implying
|
||||
/// we should go ahead and force-close any channels we have with it.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerHandleError_set_no_connection_possible(this_ptr: &mut PeerHandleError, mut val: bool) {
|
||||
unsafe { &mut *this_ptr.inner }.no_connection_possible = val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerHandleError_new(mut no_connection_possible_arg: bool) -> PeerHandleError {
|
||||
PeerHandleError { inner: Box::into_raw(Box::new(nativePeerHandleError {
|
||||
no_connection_possible: no_connection_possible_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
|
||||
use lightning::ln::peer_handler::PeerManager as nativePeerManagerImport;
|
||||
type nativePeerManager = nativePeerManagerImport<crate::ln::peer_handler::SocketDescriptor, crate::ln::msgs::ChannelMessageHandler, crate::ln::msgs::RoutingMessageHandler, crate::util::logger::Logger>;
|
||||
|
||||
/// A PeerManager manages a set of peers, described by their SocketDescriptor and marshalls socket
|
||||
/// events into messages which it passes on to its MessageHandlers.
|
||||
///
|
||||
/// Rather than using a plain PeerManager, it is preferable to use either a SimpleArcPeerManager
|
||||
/// a SimpleRefPeerManager, for conciseness. See their documentation for more details, but
|
||||
/// essentially you should default to using a SimpleRefPeerManager, and use a
|
||||
/// SimpleArcPeerManager when you require a PeerManager with a static lifetime, such as when
|
||||
/// you're using lightning-net-tokio.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct PeerManager {
|
||||
/// Nearly everyhwere, 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 nativePeerManager,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for PeerManager {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_free(this_ptr: PeerManager) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn PeerManager_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativePeerManager); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl PeerManager {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativePeerManager {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Constructs a new PeerManager with the given message handlers and node_id secret key
|
||||
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
|
||||
/// cryptographically secure random bytes.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_new(mut message_handler: crate::ln::peer_handler::MessageHandler, mut our_node_secret: crate::c_types::SecretKey, ephemeral_random_data: *const [u8; 32], mut logger: crate::util::logger::Logger) -> PeerManager {
|
||||
let mut ret = lightning::ln::peer_handler::PeerManager::new(*unsafe { Box::from_raw(message_handler.take_ptr()) }, our_node_secret.into_rust(), unsafe { &*ephemeral_random_data}, logger);
|
||||
PeerManager { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Get the list of node ids for peers which have completed the initial handshake.
|
||||
///
|
||||
/// For outbound connections, this will be the same as the their_node_id parameter passed in to
|
||||
/// new_outbound_connection, however entries will only appear once the initial handshake has
|
||||
/// completed and we are sure the remote peer has the private key for the given node_id.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_get_peer_node_ids(this_arg: &PeerManager) -> crate::c_types::derived::CVec_PublicKeyZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.get_peer_node_ids();
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::c_types::PublicKey::from_rust(&item) }); };
|
||||
local_ret.into()
|
||||
}
|
||||
|
||||
/// Indicates a new outbound connection has been established to a node with the given node_id.
|
||||
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
|
||||
/// descriptor but must disconnect the connection immediately.
|
||||
///
|
||||
/// Returns a small number of bytes to send to the remote node (currently always 50).
|
||||
///
|
||||
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
|
||||
/// socket_disconnected().
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_new_outbound_connection(this_arg: &PeerManager, mut their_node_id: crate::c_types::PublicKey, mut descriptor: crate::ln::peer_handler::SocketDescriptor) -> crate::c_types::derived::CResult_CVec_u8ZPeerHandleErrorZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.new_outbound_connection(their_node_id.into_rust(), descriptor);
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let mut local_ret_0 = Vec::new(); for item in o.drain(..) { local_ret_0.push( { item }); }; local_ret_0.into() }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::peer_handler::PeerHandleError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Indicates a new inbound connection has been established.
|
||||
///
|
||||
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
|
||||
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
|
||||
/// call socket_disconnected for the new descriptor but must disconnect the connection
|
||||
/// immediately.
|
||||
///
|
||||
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
|
||||
/// socket_disconnected called.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_new_inbound_connection(this_arg: &PeerManager, mut descriptor: crate::ln::peer_handler::SocketDescriptor) -> crate::c_types::derived::CResult_NonePeerHandleErrorZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.new_inbound_connection(descriptor);
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::peer_handler::PeerHandleError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Indicates that there is room to write data to the given socket descriptor.
|
||||
///
|
||||
/// May return an Err to indicate that the connection should be closed.
|
||||
///
|
||||
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
|
||||
/// new_*\\_connection) before returning. Thus, be very careful with reentrancy issues! The
|
||||
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
|
||||
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
|
||||
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
|
||||
/// new_\\*_connection event.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_write_buffer_space_avail(this_arg: &PeerManager, descriptor: &mut crate::ln::peer_handler::SocketDescriptor) -> crate::c_types::derived::CResult_NonePeerHandleErrorZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.write_buffer_space_avail(descriptor);
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::peer_handler::PeerHandleError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Indicates that data was read from the given socket descriptor.
|
||||
///
|
||||
/// May return an Err to indicate that the connection should be closed.
|
||||
///
|
||||
/// Will *not* call back into send_data on any descriptors to avoid reentrancy complexity.
|
||||
/// Thus, however, you almost certainly want to call process_events() after any read_event to
|
||||
/// generate send_data calls to handle responses.
|
||||
///
|
||||
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
|
||||
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
|
||||
///
|
||||
/// Panics if the descriptor was not previously registered in a new_*_connection event.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_read_event(this_arg: &PeerManager, peer_descriptor: &mut crate::ln::peer_handler::SocketDescriptor, mut data: crate::c_types::u8slice) -> crate::c_types::derived::CResult_boolPeerHandleErrorZ {
|
||||
let mut ret = unsafe { &*this_arg.inner }.read_event(peer_descriptor, data.to_slice());
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { o }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::peer_handler::PeerHandleError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
|
||||
/// Checks for any events generated by our handlers and processes them. Includes sending most
|
||||
/// response messages as well as messages generated by calls to handler functions directly (eg
|
||||
/// functions like ChannelManager::process_pending_htlc_forward or send_payment).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_process_events(this_arg: &PeerManager) {
|
||||
unsafe { &*this_arg.inner }.process_events()
|
||||
}
|
||||
|
||||
/// Indicates that the given socket descriptor's connection is now closed.
|
||||
///
|
||||
/// This must only be called if the socket has been disconnected by the peer or your own
|
||||
/// decision to disconnect it and must NOT be called in any case where other parts of this
|
||||
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect
|
||||
/// the peer.
|
||||
///
|
||||
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_socket_disconnected(this_arg: &PeerManager, descriptor: &crate::ln::peer_handler::SocketDescriptor) {
|
||||
unsafe { &*this_arg.inner }.socket_disconnected(descriptor)
|
||||
}
|
||||
|
||||
/// This function should be called roughly once every 30 seconds.
|
||||
/// It will send pings to each peer and disconnect those which did not respond to the last round of pings.
|
||||
/// Will most likely call send_data on all of the registered descriptors, thus, be very careful with reentrancy issues!
|
||||
#[no_mangle]
|
||||
pub extern "C" fn PeerManager_timer_tick_occured(this_arg: &PeerManager) {
|
||||
unsafe { &*this_arg.inner }.timer_tick_occured()
|
||||
}
|
||||
|
8
lightning-c-bindings/src/routing/mod.rs
Normal file
8
lightning-c-bindings/src/routing/mod.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
//! Structs and impls for receiving messages about the network and storing the topology live here.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
pub mod router;
|
||||
pub mod network_graph;
|
795
lightning-c-bindings/src/routing/network_graph.rs
Normal file
795
lightning-c-bindings/src/routing/network_graph.rs
Normal file
|
@ -0,0 +1,795 @@
|
|||
//! The top-level network map tracking logic lives here.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
|
||||
use lightning::routing::network_graph::NetworkGraph as nativeNetworkGraphImport;
|
||||
type nativeNetworkGraph = nativeNetworkGraphImport;
|
||||
|
||||
/// Represents the network as nodes and channels between them
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct NetworkGraph {
|
||||
/// Nearly everyhwere, 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 nativeNetworkGraph,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for NetworkGraph {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetworkGraph_free(this_ptr: NetworkGraph) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn NetworkGraph_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeNetworkGraph); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl NetworkGraph {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeNetworkGraph {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::routing::network_graph::LockedNetworkGraph as nativeLockedNetworkGraphImport;
|
||||
type nativeLockedNetworkGraph = nativeLockedNetworkGraphImport<'static>;
|
||||
|
||||
/// A simple newtype for RwLockReadGuard<'a, NetworkGraph>.
|
||||
/// This exists only to make accessing a RwLock<NetworkGraph> possible from
|
||||
/// the C bindings, as it can be done directly in Rust code.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct LockedNetworkGraph {
|
||||
/// Nearly everyhwere, 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 nativeLockedNetworkGraph,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for LockedNetworkGraph {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LockedNetworkGraph_free(this_ptr: LockedNetworkGraph) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn LockedNetworkGraph_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeLockedNetworkGraph); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl LockedNetworkGraph {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeLockedNetworkGraph {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::routing::network_graph::NetGraphMsgHandler as nativeNetGraphMsgHandlerImport;
|
||||
type nativeNetGraphMsgHandler = nativeNetGraphMsgHandlerImport<crate::chain::chaininterface::ChainWatchInterface, crate::util::logger::Logger>;
|
||||
|
||||
/// Receives and validates network updates from peers,
|
||||
/// stores authentic and relevant data as a network graph.
|
||||
/// This network graph is then used for routing payments.
|
||||
/// Provides interface to help with initial routing sync by
|
||||
/// serving historical announcements.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct NetGraphMsgHandler {
|
||||
/// Nearly everyhwere, 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 nativeNetGraphMsgHandler,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for NetGraphMsgHandler {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetGraphMsgHandler_free(this_ptr: NetGraphMsgHandler) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn NetGraphMsgHandler_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeNetGraphMsgHandler); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl NetGraphMsgHandler {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeNetGraphMsgHandler {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Creates a new tracker of the actual state of the network of channels and nodes,
|
||||
/// assuming a fresh network graph.
|
||||
/// Chain monitor is used to make sure announced channels exist on-chain,
|
||||
/// channel data is correct, and that the announcement is signed with
|
||||
/// channel owners' keys.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetGraphMsgHandler_new(mut chain_monitor: crate::chain::chaininterface::ChainWatchInterface, mut logger: crate::util::logger::Logger) -> NetGraphMsgHandler {
|
||||
let mut ret = lightning::routing::network_graph::NetGraphMsgHandler::new(chain_monitor, logger);
|
||||
NetGraphMsgHandler { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Creates a new tracker of the actual state of the network of channels and nodes,
|
||||
/// assuming an existing Network Graph.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetGraphMsgHandler_from_net_graph(mut chain_monitor: crate::chain::chaininterface::ChainWatchInterface, mut logger: crate::util::logger::Logger, mut network_graph: crate::routing::network_graph::NetworkGraph) -> NetGraphMsgHandler {
|
||||
let mut ret = lightning::routing::network_graph::NetGraphMsgHandler::from_net_graph(chain_monitor, logger, *unsafe { Box::from_raw(network_graph.take_ptr()) });
|
||||
NetGraphMsgHandler { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Take a read lock on the network_graph and return it in the C-bindings
|
||||
/// newtype helper. This is likely only useful when called via the C
|
||||
/// bindings as you can call `self.network_graph.read().unwrap()` in Rust
|
||||
/// yourself.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetGraphMsgHandler_read_locked_graph(this_arg: &NetGraphMsgHandler) -> crate::routing::network_graph::LockedNetworkGraph {
|
||||
let mut ret = unsafe { &*this_arg.inner }.read_locked_graph();
|
||||
crate::routing::network_graph::LockedNetworkGraph { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Get a reference to the NetworkGraph which this read-lock contains.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn LockedNetworkGraph_graph(this_arg: &LockedNetworkGraph) -> crate::routing::network_graph::NetworkGraph {
|
||||
let mut ret = unsafe { &*this_arg.inner }.graph();
|
||||
crate::routing::network_graph::NetworkGraph { inner: unsafe { ( (&(*ret) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetGraphMsgHandler_as_RoutingMessageHandler(this_arg: *const NetGraphMsgHandler) -> crate::ln::msgs::RoutingMessageHandler {
|
||||
crate::ln::msgs::RoutingMessageHandler {
|
||||
this_arg: unsafe { (*this_arg).inner as *mut c_void },
|
||||
free: None,
|
||||
handle_node_announcement: NetGraphMsgHandler_RoutingMessageHandler_handle_node_announcement,
|
||||
handle_channel_announcement: NetGraphMsgHandler_RoutingMessageHandler_handle_channel_announcement,
|
||||
handle_channel_update: NetGraphMsgHandler_RoutingMessageHandler_handle_channel_update,
|
||||
handle_htlc_fail_channel_update: NetGraphMsgHandler_RoutingMessageHandler_handle_htlc_fail_channel_update,
|
||||
get_next_channel_announcements: NetGraphMsgHandler_RoutingMessageHandler_get_next_channel_announcements,
|
||||
get_next_node_announcements: NetGraphMsgHandler_RoutingMessageHandler_get_next_node_announcements,
|
||||
should_request_full_sync: NetGraphMsgHandler_RoutingMessageHandler_should_request_full_sync,
|
||||
}
|
||||
}
|
||||
use lightning::ln::msgs::RoutingMessageHandler as RoutingMessageHandlerTraitImport;
|
||||
#[must_use]
|
||||
extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_handle_node_announcement(this_arg: *const c_void, msg: &crate::ln::msgs::NodeAnnouncement) -> crate::c_types::derived::CResult_boolLightningErrorZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeNetGraphMsgHandler) }.handle_node_announcement(unsafe { &*msg.inner });
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { o }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::LightningError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_handle_channel_announcement(this_arg: *const c_void, msg: &crate::ln::msgs::ChannelAnnouncement) -> crate::c_types::derived::CResult_boolLightningErrorZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeNetGraphMsgHandler) }.handle_channel_announcement(unsafe { &*msg.inner });
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { o }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::LightningError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_handle_htlc_fail_channel_update(this_arg: *const c_void, update: &crate::ln::msgs::HTLCFailChannelUpdate) {
|
||||
unsafe { &mut *(this_arg as *mut nativeNetGraphMsgHandler) }.handle_htlc_fail_channel_update(&update.to_native())
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_handle_channel_update(this_arg: *const c_void, msg: &crate::ln::msgs::ChannelUpdate) -> crate::c_types::derived::CResult_boolLightningErrorZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeNetGraphMsgHandler) }.handle_channel_update(unsafe { &*msg.inner });
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { o }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::LightningError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_get_next_channel_announcements(this_arg: *const c_void, mut starting_point: u64, mut batch_amount: u8) -> crate::c_types::derived::CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeNetGraphMsgHandler) }.get_next_channel_announcements(starting_point, batch_amount);
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { let (mut orig_ret_0_0, mut orig_ret_0_1, mut orig_ret_0_2) = item; let mut local_orig_ret_0_1 = crate::ln::msgs::ChannelUpdate { inner: if orig_ret_0_1.is_none() { std::ptr::null_mut() } else { { Box::into_raw(Box::new((orig_ret_0_1.unwrap()))) } }, is_owned: true }; let mut local_orig_ret_0_2 = crate::ln::msgs::ChannelUpdate { inner: if orig_ret_0_2.is_none() { std::ptr::null_mut() } else { { Box::into_raw(Box::new((orig_ret_0_2.unwrap()))) } }, is_owned: true }; let mut local_ret_0 = (crate::ln::msgs::ChannelAnnouncement { inner: Box::into_raw(Box::new(orig_ret_0_0)), is_owned: true }, local_orig_ret_0_1, local_orig_ret_0_2).into(); local_ret_0 }); };
|
||||
local_ret.into()
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_get_next_node_announcements(this_arg: *const c_void, mut starting_point: crate::c_types::PublicKey, mut batch_amount: u8) -> crate::c_types::derived::CVec_NodeAnnouncementZ {
|
||||
let mut local_starting_point_base = if starting_point.is_null() { None } else { Some( { starting_point.into_rust() }) }; let mut local_starting_point = local_starting_point_base.as_ref();
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeNetGraphMsgHandler) }.get_next_node_announcements(local_starting_point, batch_amount);
|
||||
let mut local_ret = Vec::new(); for item in ret.drain(..) { local_ret.push( { crate::ln::msgs::NodeAnnouncement { inner: Box::into_raw(Box::new(item)), is_owned: true } }); };
|
||||
local_ret.into()
|
||||
}
|
||||
#[must_use]
|
||||
extern "C" fn NetGraphMsgHandler_RoutingMessageHandler_should_request_full_sync(this_arg: *const c_void, _node_id: crate::c_types::PublicKey) -> bool {
|
||||
let mut ret = unsafe { &mut *(this_arg as *mut nativeNetGraphMsgHandler) }.should_request_full_sync(&_node_id.into_rust());
|
||||
ret
|
||||
}
|
||||
|
||||
|
||||
use lightning::routing::network_graph::DirectionalChannelInfo as nativeDirectionalChannelInfoImport;
|
||||
type nativeDirectionalChannelInfo = nativeDirectionalChannelInfoImport;
|
||||
|
||||
/// Details about one direction of a channel. Received
|
||||
/// within a channel update.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct DirectionalChannelInfo {
|
||||
/// Nearly everyhwere, 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 nativeDirectionalChannelInfo,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for DirectionalChannelInfo {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_free(this_ptr: DirectionalChannelInfo) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn DirectionalChannelInfo_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeDirectionalChannelInfo); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl DirectionalChannelInfo {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeDirectionalChannelInfo {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// When the last update to the channel direction was issued.
|
||||
/// Value is opaque, as set in the announcement.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_get_last_update(this_ptr: &DirectionalChannelInfo) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.last_update;
|
||||
(*inner_val)
|
||||
}
|
||||
/// When the last update to the channel direction was issued.
|
||||
/// Value is opaque, as set in the announcement.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_set_last_update(this_ptr: &mut DirectionalChannelInfo, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.last_update = val;
|
||||
}
|
||||
/// Whether the channel can be currently used for payments (in this one direction).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_get_enabled(this_ptr: &DirectionalChannelInfo) -> bool {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.enabled;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Whether the channel can be currently used for payments (in this one direction).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_set_enabled(this_ptr: &mut DirectionalChannelInfo, mut val: bool) {
|
||||
unsafe { &mut *this_ptr.inner }.enabled = val;
|
||||
}
|
||||
/// The difference in CLTV values that you must have when routing through this channel.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_get_cltv_expiry_delta(this_ptr: &DirectionalChannelInfo) -> u16 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.cltv_expiry_delta;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The difference in CLTV values that you must have when routing through this channel.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_set_cltv_expiry_delta(this_ptr: &mut DirectionalChannelInfo, mut val: u16) {
|
||||
unsafe { &mut *this_ptr.inner }.cltv_expiry_delta = val;
|
||||
}
|
||||
/// The minimum value, which must be relayed to the next hop via the channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_get_htlc_minimum_msat(this_ptr: &DirectionalChannelInfo) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.htlc_minimum_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The minimum value, which must be relayed to the next hop via the channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_set_htlc_minimum_msat(this_ptr: &mut DirectionalChannelInfo, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.htlc_minimum_msat = val;
|
||||
}
|
||||
/// Most recent update for the channel received from the network
|
||||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_get_last_update_message(this_ptr: &DirectionalChannelInfo) -> crate::ln::msgs::ChannelUpdate {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.last_update_message;
|
||||
let mut local_inner_val = crate::ln::msgs::ChannelUpdate { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
|
||||
local_inner_val
|
||||
}
|
||||
/// Most recent update for the channel received from the network
|
||||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_set_last_update_message(this_ptr: &mut DirectionalChannelInfo, mut val: crate::ln::msgs::ChannelUpdate) {
|
||||
let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_ptr()) } }) };
|
||||
unsafe { &mut *this_ptr.inner }.last_update_message = local_val;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_write(obj: *const DirectionalChannelInfo) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DirectionalChannelInfo_read(ser: crate::c_types::u8slice) -> DirectionalChannelInfo {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
DirectionalChannelInfo { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
DirectionalChannelInfo { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::routing::network_graph::ChannelInfo as nativeChannelInfoImport;
|
||||
type nativeChannelInfo = nativeChannelInfoImport;
|
||||
|
||||
/// Details about a channel (both directions).
|
||||
/// Received within a channel announcement.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelInfo {
|
||||
/// Nearly everyhwere, 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 nativeChannelInfo,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelInfo {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_free(this_ptr: ChannelInfo) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelInfo_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelInfo); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelInfo {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelInfo {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// Source node of the first direction of a channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_get_node_one(this_ptr: &ChannelInfo) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.node_one;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// Source node of the first direction of a channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_set_node_one(this_ptr: &mut ChannelInfo, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.node_one = val.into_rust();
|
||||
}
|
||||
/// Details about the first direction of a channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_get_one_to_two(this_ptr: &ChannelInfo) -> crate::routing::network_graph::DirectionalChannelInfo {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.one_to_two;
|
||||
let mut local_inner_val = crate::routing::network_graph::DirectionalChannelInfo { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
|
||||
local_inner_val
|
||||
}
|
||||
/// Details about the first direction of a channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_set_one_to_two(this_ptr: &mut ChannelInfo, mut val: crate::routing::network_graph::DirectionalChannelInfo) {
|
||||
let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_ptr()) } }) };
|
||||
unsafe { &mut *this_ptr.inner }.one_to_two = local_val;
|
||||
}
|
||||
/// Source node of the second direction of a channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_get_node_two(this_ptr: &ChannelInfo) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.node_two;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// Source node of the second direction of a channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_set_node_two(this_ptr: &mut ChannelInfo, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.node_two = val.into_rust();
|
||||
}
|
||||
/// Details about the second direction of a channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_get_two_to_one(this_ptr: &ChannelInfo) -> crate::routing::network_graph::DirectionalChannelInfo {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.two_to_one;
|
||||
let mut local_inner_val = crate::routing::network_graph::DirectionalChannelInfo { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
|
||||
local_inner_val
|
||||
}
|
||||
/// Details about the second direction of a channel
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_set_two_to_one(this_ptr: &mut ChannelInfo, mut val: crate::routing::network_graph::DirectionalChannelInfo) {
|
||||
let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_ptr()) } }) };
|
||||
unsafe { &mut *this_ptr.inner }.two_to_one = local_val;
|
||||
}
|
||||
/// An initial announcement of the channel
|
||||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_get_announcement_message(this_ptr: &ChannelInfo) -> crate::ln::msgs::ChannelAnnouncement {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.announcement_message;
|
||||
let mut local_inner_val = crate::ln::msgs::ChannelAnnouncement { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
|
||||
local_inner_val
|
||||
}
|
||||
/// An initial announcement of the channel
|
||||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_set_announcement_message(this_ptr: &mut ChannelInfo, mut val: crate::ln::msgs::ChannelAnnouncement) {
|
||||
let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_ptr()) } }) };
|
||||
unsafe { &mut *this_ptr.inner }.announcement_message = local_val;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_write(obj: *const ChannelInfo) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelInfo_read(ser: crate::c_types::u8slice) -> ChannelInfo {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
ChannelInfo { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
ChannelInfo { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::routing::network_graph::RoutingFees as nativeRoutingFeesImport;
|
||||
type nativeRoutingFees = nativeRoutingFeesImport;
|
||||
|
||||
/// Fees for routing via a given channel or a node
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct RoutingFees {
|
||||
/// Nearly everyhwere, 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 nativeRoutingFees,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for RoutingFees {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RoutingFees_free(this_ptr: RoutingFees) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn RoutingFees_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeRoutingFees); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl RoutingFees {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeRoutingFees {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for RoutingFees {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn RoutingFees_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRoutingFees)).clone() })) as *mut c_void
|
||||
}
|
||||
/// Flat routing fee in satoshis
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RoutingFees_get_base_msat(this_ptr: &RoutingFees) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.base_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Flat routing fee in satoshis
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RoutingFees_set_base_msat(this_ptr: &mut RoutingFees, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.base_msat = val;
|
||||
}
|
||||
/// Liquidity-based routing fee in millionths of a routed amount.
|
||||
/// In other words, 10000 is 1%.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RoutingFees_get_proportional_millionths(this_ptr: &RoutingFees) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.proportional_millionths;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Liquidity-based routing fee in millionths of a routed amount.
|
||||
/// In other words, 10000 is 1%.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RoutingFees_set_proportional_millionths(this_ptr: &mut RoutingFees, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.proportional_millionths = val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RoutingFees_new(mut base_msat_arg: u32, mut proportional_millionths_arg: u32) -> RoutingFees {
|
||||
RoutingFees { inner: Box::into_raw(Box::new(nativeRoutingFees {
|
||||
base_msat: base_msat_arg,
|
||||
proportional_millionths: proportional_millionths_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RoutingFees_read(ser: crate::c_types::u8slice) -> RoutingFees {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
RoutingFees { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
RoutingFees { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RoutingFees_write(obj: *const RoutingFees) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
|
||||
use lightning::routing::network_graph::NodeAnnouncementInfo as nativeNodeAnnouncementInfoImport;
|
||||
type nativeNodeAnnouncementInfo = nativeNodeAnnouncementInfoImport;
|
||||
|
||||
/// Information received in the latest node_announcement from this node.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct NodeAnnouncementInfo {
|
||||
/// Nearly everyhwere, 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 nativeNodeAnnouncementInfo,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for NodeAnnouncementInfo {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_free(this_ptr: NodeAnnouncementInfo) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn NodeAnnouncementInfo_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeNodeAnnouncementInfo); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl NodeAnnouncementInfo {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeNodeAnnouncementInfo {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// When the last known update to the node state was issued.
|
||||
/// Value is opaque, as set in the announcement.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_get_last_update(this_ptr: &NodeAnnouncementInfo) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.last_update;
|
||||
(*inner_val)
|
||||
}
|
||||
/// When the last known update to the node state was issued.
|
||||
/// Value is opaque, as set in the announcement.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_set_last_update(this_ptr: &mut NodeAnnouncementInfo, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.last_update = val;
|
||||
}
|
||||
/// Color assigned to the node
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_get_rgb(this_ptr: &NodeAnnouncementInfo) -> *const [u8; 3] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.rgb;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// Color assigned to the node
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_set_rgb(this_ptr: &mut NodeAnnouncementInfo, mut val: crate::c_types::ThreeBytes) {
|
||||
unsafe { &mut *this_ptr.inner }.rgb = val.data;
|
||||
}
|
||||
/// Moniker assigned to the node.
|
||||
/// May be invalid or malicious (eg control chars),
|
||||
/// should not be exposed to the user.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_get_alias(this_ptr: &NodeAnnouncementInfo) -> *const [u8; 32] {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.alias;
|
||||
&(*inner_val)
|
||||
}
|
||||
/// Moniker assigned to the node.
|
||||
/// May be invalid or malicious (eg control chars),
|
||||
/// should not be exposed to the user.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_set_alias(this_ptr: &mut NodeAnnouncementInfo, mut val: crate::c_types::ThirtyTwoBytes) {
|
||||
unsafe { &mut *this_ptr.inner }.alias = val.data;
|
||||
}
|
||||
/// Internet-level addresses via which one can connect to the node
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_set_addresses(this_ptr: &mut NodeAnnouncementInfo, mut val: crate::c_types::derived::CVec_NetAddressZ) {
|
||||
let mut local_val = Vec::new(); for mut item in val.into_rust().drain(..) { local_val.push( { item.into_native() }); };
|
||||
unsafe { &mut *this_ptr.inner }.addresses = local_val;
|
||||
}
|
||||
/// An initial announcement of the node
|
||||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_get_announcement_message(this_ptr: &NodeAnnouncementInfo) -> crate::ln::msgs::NodeAnnouncement {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.announcement_message;
|
||||
let mut local_inner_val = crate::ln::msgs::NodeAnnouncement { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
|
||||
local_inner_val
|
||||
}
|
||||
/// An initial announcement of the node
|
||||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_set_announcement_message(this_ptr: &mut NodeAnnouncementInfo, mut val: crate::ln::msgs::NodeAnnouncement) {
|
||||
let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_ptr()) } }) };
|
||||
unsafe { &mut *this_ptr.inner }.announcement_message = local_val;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_write(obj: *const NodeAnnouncementInfo) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeAnnouncementInfo_read(ser: crate::c_types::u8slice) -> NodeAnnouncementInfo {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
NodeAnnouncementInfo { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
NodeAnnouncementInfo { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::routing::network_graph::NodeInfo as nativeNodeInfoImport;
|
||||
type nativeNodeInfo = nativeNodeInfoImport;
|
||||
|
||||
/// Details about a node in the network, known from the network announcement.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct NodeInfo {
|
||||
/// Nearly everyhwere, 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 nativeNodeInfo,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for NodeInfo {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_free(this_ptr: NodeInfo) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn NodeInfo_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeNodeInfo); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl NodeInfo {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeNodeInfo {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// All valid channels a node has announced
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_set_channels(this_ptr: &mut NodeInfo, mut val: crate::c_types::derived::CVec_u64Z) {
|
||||
let mut local_val = Vec::new(); for mut item in val.into_rust().drain(..) { local_val.push( { item }); };
|
||||
unsafe { &mut *this_ptr.inner }.channels = local_val;
|
||||
}
|
||||
/// Lowest fees enabling routing via any of the enabled, known channels to a node.
|
||||
/// The two fields (flat and proportional fee) are independent,
|
||||
/// meaning they don't have to refer to the same channel.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_get_lowest_inbound_channel_fees(this_ptr: &NodeInfo) -> crate::routing::network_graph::RoutingFees {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.lowest_inbound_channel_fees;
|
||||
let mut local_inner_val = crate::routing::network_graph::RoutingFees { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
|
||||
local_inner_val
|
||||
}
|
||||
/// Lowest fees enabling routing via any of the enabled, known channels to a node.
|
||||
/// The two fields (flat and proportional fee) are independent,
|
||||
/// meaning they don't have to refer to the same channel.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_set_lowest_inbound_channel_fees(this_ptr: &mut NodeInfo, mut val: crate::routing::network_graph::RoutingFees) {
|
||||
let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_ptr()) } }) };
|
||||
unsafe { &mut *this_ptr.inner }.lowest_inbound_channel_fees = local_val;
|
||||
}
|
||||
/// More information about a node from node_announcement.
|
||||
/// Optional because we store a Node entry after learning about it from
|
||||
/// a channel announcement, but before receiving a node announcement.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_get_announcement_info(this_ptr: &NodeInfo) -> crate::routing::network_graph::NodeAnnouncementInfo {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.announcement_info;
|
||||
let mut local_inner_val = crate::routing::network_graph::NodeAnnouncementInfo { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false };
|
||||
local_inner_val
|
||||
}
|
||||
/// More information about a node from node_announcement.
|
||||
/// Optional because we store a Node entry after learning about it from
|
||||
/// a channel announcement, but before receiving a node announcement.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_set_announcement_info(this_ptr: &mut NodeInfo, mut val: crate::routing::network_graph::NodeAnnouncementInfo) {
|
||||
let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_ptr()) } }) };
|
||||
unsafe { &mut *this_ptr.inner }.announcement_info = local_val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_new(mut channels_arg: crate::c_types::derived::CVec_u64Z, mut lowest_inbound_channel_fees_arg: crate::routing::network_graph::RoutingFees, mut announcement_info_arg: crate::routing::network_graph::NodeAnnouncementInfo) -> NodeInfo {
|
||||
let mut local_channels_arg = Vec::new(); for mut item in channels_arg.into_rust().drain(..) { local_channels_arg.push( { item }); };
|
||||
let mut local_lowest_inbound_channel_fees_arg = if lowest_inbound_channel_fees_arg.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(lowest_inbound_channel_fees_arg.take_ptr()) } }) };
|
||||
let mut local_announcement_info_arg = if announcement_info_arg.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(announcement_info_arg.take_ptr()) } }) };
|
||||
NodeInfo { inner: Box::into_raw(Box::new(nativeNodeInfo {
|
||||
channels: local_channels_arg,
|
||||
lowest_inbound_channel_fees: local_lowest_inbound_channel_fees_arg,
|
||||
announcement_info: local_announcement_info_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_write(obj: *const NodeInfo) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NodeInfo_read(ser: crate::c_types::u8slice) -> NodeInfo {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
NodeInfo { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
NodeInfo { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetworkGraph_write(obj: *const NetworkGraph) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetworkGraph_read(ser: crate::c_types::u8slice) -> NetworkGraph {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
NetworkGraph { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
NetworkGraph { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
/// Creates a new, empty, network graph.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetworkGraph_new() -> crate::routing::network_graph::NetworkGraph {
|
||||
let mut ret = lightning::routing::network_graph::NetworkGraph::new();
|
||||
crate::routing::network_graph::NetworkGraph { inner: Box::into_raw(Box::new(ret)), is_owned: true }
|
||||
}
|
||||
|
||||
/// Close a channel if a corresponding HTLC fail was sent.
|
||||
/// If permanent, removes a channel from the local storage.
|
||||
/// May cause the removal of nodes too, if this was their last channel.
|
||||
/// If not permanent, makes channels unavailable for routing.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn NetworkGraph_close_channel_from_update(this_arg: &mut NetworkGraph, mut short_channel_id: u64, mut is_permanent: bool) {
|
||||
unsafe { &mut (*(this_arg.inner as *mut nativeNetworkGraph)) }.close_channel_from_update(short_channel_id, is_permanent)
|
||||
}
|
||||
|
318
lightning-c-bindings/src/routing/router.rs
Normal file
318
lightning-c-bindings/src/routing/router.rs
Normal file
|
@ -0,0 +1,318 @@
|
|||
//! The top-level routing/network map tracking logic lives here.
|
||||
//!
|
||||
//! You probably want to create a NetGraphMsgHandler and use that as your RoutingMessageHandler and then
|
||||
//! interrogate it to get routes for your own payments.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
|
||||
use lightning::routing::router::RouteHop as nativeRouteHopImport;
|
||||
type nativeRouteHop = nativeRouteHopImport;
|
||||
|
||||
/// A hop in a route
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct RouteHop {
|
||||
/// Nearly everyhwere, 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 nativeRouteHop,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for RouteHop {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_free(this_ptr: RouteHop) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn RouteHop_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeRouteHop); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl RouteHop {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeRouteHop {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for RouteHop {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn RouteHop_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRouteHop)).clone() })) as *mut c_void
|
||||
}
|
||||
/// The node_id of the node at this hop.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_get_pubkey(this_ptr: &RouteHop) -> crate::c_types::PublicKey {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.pubkey;
|
||||
crate::c_types::PublicKey::from_rust(&(*inner_val))
|
||||
}
|
||||
/// The node_id of the node at this hop.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_set_pubkey(this_ptr: &mut RouteHop, mut val: crate::c_types::PublicKey) {
|
||||
unsafe { &mut *this_ptr.inner }.pubkey = val.into_rust();
|
||||
}
|
||||
/// The channel that should be used from the previous hop to reach this node.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_get_short_channel_id(this_ptr: &RouteHop) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.short_channel_id;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The channel that should be used from the previous hop to reach this node.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_set_short_channel_id(this_ptr: &mut RouteHop, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.short_channel_id = val;
|
||||
}
|
||||
/// The fee taken on this hop. For the last hop, this should be the full value of the payment.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_get_fee_msat(this_ptr: &RouteHop) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.fee_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The fee taken on this hop. For the last hop, this should be the full value of the payment.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_set_fee_msat(this_ptr: &mut RouteHop, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.fee_msat = val;
|
||||
}
|
||||
/// The CLTV delta added for this hop. For the last hop, this should be the full CLTV value
|
||||
/// expected at the destination, in excess of the current block height.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_get_cltv_expiry_delta(this_ptr: &RouteHop) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.cltv_expiry_delta;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The CLTV delta added for this hop. For the last hop, this should be the full CLTV value
|
||||
/// expected at the destination, in excess of the current block height.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHop_set_cltv_expiry_delta(this_ptr: &mut RouteHop, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.cltv_expiry_delta = val;
|
||||
}
|
||||
|
||||
use lightning::routing::router::Route as nativeRouteImport;
|
||||
type nativeRoute = nativeRouteImport;
|
||||
|
||||
/// A route directs a payment from the sender (us) to the recipient. If the recipient supports MPP,
|
||||
/// it can take multiple paths. Each path is composed of one or more hops through the network.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct Route {
|
||||
/// Nearly everyhwere, 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 nativeRoute,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for Route {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Route_free(this_ptr: Route) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn Route_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeRoute); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl Route {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeRoute {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for Route {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn Route_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeRoute)).clone() })) as *mut c_void
|
||||
}
|
||||
/// The list of routes taken for a single (potentially-)multi-part payment. The pubkey of the
|
||||
/// last RouteHop in each path must be the same.
|
||||
/// Each entry represents a list of hops, NOT INCLUDING our own, where the last hop is the
|
||||
/// destination. Thus, this must always be at least length one. While the maximum length of any
|
||||
/// given path is variable, keeping the length of any path to less than 20 should currently
|
||||
/// ensure it is viable.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Route_set_paths(this_ptr: &mut Route, mut val: crate::c_types::derived::CVec_CVec_RouteHopZZ) {
|
||||
let mut local_val = Vec::new(); for mut item in val.into_rust().drain(..) { local_val.push( { let mut local_val_0 = Vec::new(); for mut item in item.into_rust().drain(..) { local_val_0.push( { *unsafe { Box::from_raw(item.take_ptr()) } }); }; local_val_0 }); };
|
||||
unsafe { &mut *this_ptr.inner }.paths = local_val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Route_new(mut paths_arg: crate::c_types::derived::CVec_CVec_RouteHopZZ) -> Route {
|
||||
let mut local_paths_arg = Vec::new(); for mut item in paths_arg.into_rust().drain(..) { local_paths_arg.push( { let mut local_paths_arg_0 = Vec::new(); for mut item in item.into_rust().drain(..) { local_paths_arg_0.push( { *unsafe { Box::from_raw(item.take_ptr()) } }); }; local_paths_arg_0 }); };
|
||||
Route { inner: Box::into_raw(Box::new(nativeRoute {
|
||||
paths: local_paths_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Route_write(obj: *const Route) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Route_read(ser: crate::c_types::u8slice) -> Route {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
Route { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
Route { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::routing::router::RouteHint as nativeRouteHintImport;
|
||||
type nativeRouteHint = nativeRouteHintImport;
|
||||
|
||||
/// A channel descriptor which provides a last-hop route to get_route
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct RouteHint {
|
||||
/// Nearly everyhwere, 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 is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for RouteHint {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn RouteHint_free(this_ptr: RouteHint) { }
|
||||
#[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); }
|
||||
}
|
||||
#[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_ptr(mut self) -> *mut nativeRouteHint {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
/// 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 {
|
||||
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) {
|
||||
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 {
|
||||
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) {
|
||||
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::routing::network_graph::RoutingFees {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.fees;
|
||||
crate::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::routing::network_graph::RoutingFees) {
|
||||
unsafe { &mut *this_ptr.inner }.fees = *unsafe { Box::from_raw(val.take_ptr()) };
|
||||
}
|
||||
/// 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 {
|
||||
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) {
|
||||
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) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.htlc_minimum_msat;
|
||||
(*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: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.htlc_minimum_msat = val;
|
||||
}
|
||||
#[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::routing::network_graph::RoutingFees, mut cltv_expiry_delta_arg: u16, mut htlc_minimum_msat_arg: u64) -> RouteHint {
|
||||
RouteHint { inner: Box::into_raw(Box::new(nativeRouteHint {
|
||||
src_node_id: src_node_id_arg.into_rust(),
|
||||
short_channel_id: short_channel_id_arg,
|
||||
fees: *unsafe { Box::from_raw(fees_arg.take_ptr()) },
|
||||
cltv_expiry_delta: cltv_expiry_delta_arg,
|
||||
htlc_minimum_msat: htlc_minimum_msat_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
/// Gets a route from us to the given target node.
|
||||
///
|
||||
/// Extra routing hops between known nodes and the target will be used if they are included in
|
||||
/// last_hops.
|
||||
///
|
||||
/// If some channels aren't announced, it may be useful to fill in a first_hops with the
|
||||
/// results from a local ChannelManager::list_usable_channels() call. If it is filled in, our
|
||||
/// view of our local channels (from net_graph_msg_handler) will be ignored, and only those in first_hops
|
||||
/// will be used.
|
||||
///
|
||||
/// Panics if first_hops contains channels without short_channel_ids
|
||||
/// (ChannelManager::list_usable_channels will never include such channels).
|
||||
///
|
||||
/// The fees on channels from us to next-hops are ignored (as they are assumed to all be
|
||||
/// equal), however the enabled/disabled bit on such channels as well as the htlc_minimum_msat
|
||||
/// *is* checked as they may change based on the receiving node.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn get_route(our_node_id: crate::c_types::PublicKey, network: &crate::routing::network_graph::NetworkGraph, target: crate::c_types::PublicKey, mut 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::util::logger::Logger) -> crate::c_types::derived::CResult_RouteLightningErrorZ {
|
||||
let mut local_first_hops_base = if first_hops.is_null() { 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 } }); };
|
||||
let mut ret = lightning::routing::router::get_route(&our_node_id.into_rust(), unsafe { &*network.inner }, &target.into_rust(), local_first_hops, &local_last_hops[..], final_value_msat, final_cltv, logger);
|
||||
let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::routing::router::Route { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::LightningError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };
|
||||
local_ret
|
||||
}
|
||||
|
687
lightning-c-bindings/src/util/config.rs
Normal file
687
lightning-c-bindings/src/util/config.rs
Normal file
|
@ -0,0 +1,687 @@
|
|||
//! Various user-configurable channel limits and settings which ChannelManager
|
||||
//! applies for you.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
|
||||
use lightning::util::config::ChannelHandshakeConfig as nativeChannelHandshakeConfigImport;
|
||||
type nativeChannelHandshakeConfig = nativeChannelHandshakeConfigImport;
|
||||
|
||||
/// Configuration we set when applicable.
|
||||
///
|
||||
/// Default::default() provides sane defaults.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelHandshakeConfig {
|
||||
/// Nearly everyhwere, 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 nativeChannelHandshakeConfig,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelHandshakeConfig {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_free(this_ptr: ChannelHandshakeConfig) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelHandshakeConfig_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelHandshakeConfig); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelHandshakeConfig {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelHandshakeConfig {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for ChannelHandshakeConfig {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn ChannelHandshakeConfig_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelHandshakeConfig)).clone() })) as *mut c_void
|
||||
}
|
||||
/// Confirmations we will wait for before considering the channel locked in.
|
||||
/// Applied only for inbound channels (see ChannelHandshakeLimits::max_minimum_depth for the
|
||||
/// equivalent limit applied to outbound channels).
|
||||
///
|
||||
/// Default value: 6.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_get_minimum_depth(this_ptr: &ChannelHandshakeConfig) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.minimum_depth;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Confirmations we will wait for before considering the channel locked in.
|
||||
/// Applied only for inbound channels (see ChannelHandshakeLimits::max_minimum_depth for the
|
||||
/// equivalent limit applied to outbound channels).
|
||||
///
|
||||
/// Default value: 6.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_set_minimum_depth(this_ptr: &mut ChannelHandshakeConfig, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.minimum_depth = val;
|
||||
}
|
||||
/// Set to the amount of time we require our counterparty to wait to claim their money.
|
||||
///
|
||||
/// It's one of the main parameter of our security model. We (or one of our watchtowers) MUST
|
||||
/// be online to check for peer having broadcast a revoked transaction to steal our funds
|
||||
/// at least once every our_to_self_delay blocks.
|
||||
///
|
||||
/// Meanwhile, asking for a too high delay, we bother peer to freeze funds for nothing in
|
||||
/// case of an honest unilateral channel close, which implicitly decrease the economic value of
|
||||
/// our channel.
|
||||
///
|
||||
/// Default value: BREAKDOWN_TIMEOUT (currently 144), we enforce it as a minimum at channel
|
||||
/// opening so you can tweak config to ask for more security, not less.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_get_our_to_self_delay(this_ptr: &ChannelHandshakeConfig) -> u16 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.our_to_self_delay;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Set to the amount of time we require our counterparty to wait to claim their money.
|
||||
///
|
||||
/// It's one of the main parameter of our security model. We (or one of our watchtowers) MUST
|
||||
/// be online to check for peer having broadcast a revoked transaction to steal our funds
|
||||
/// at least once every our_to_self_delay blocks.
|
||||
///
|
||||
/// Meanwhile, asking for a too high delay, we bother peer to freeze funds for nothing in
|
||||
/// case of an honest unilateral channel close, which implicitly decrease the economic value of
|
||||
/// our channel.
|
||||
///
|
||||
/// Default value: BREAKDOWN_TIMEOUT (currently 144), we enforce it as a minimum at channel
|
||||
/// opening so you can tweak config to ask for more security, not less.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_set_our_to_self_delay(this_ptr: &mut ChannelHandshakeConfig, mut val: u16) {
|
||||
unsafe { &mut *this_ptr.inner }.our_to_self_delay = val;
|
||||
}
|
||||
/// Set to the smallest value HTLC we will accept to process.
|
||||
///
|
||||
/// This value is sent to our counterparty on channel-open and we close the channel any time
|
||||
/// our counterparty misbehaves by sending us an HTLC with a value smaller than this.
|
||||
///
|
||||
/// Default value: 1. If the value is less than 1, it is ignored and set to 1, as is required
|
||||
/// by the protocol.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_get_our_htlc_minimum_msat(this_ptr: &ChannelHandshakeConfig) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.our_htlc_minimum_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Set to the smallest value HTLC we will accept to process.
|
||||
///
|
||||
/// This value is sent to our counterparty on channel-open and we close the channel any time
|
||||
/// our counterparty misbehaves by sending us an HTLC with a value smaller than this.
|
||||
///
|
||||
/// Default value: 1. If the value is less than 1, it is ignored and set to 1, as is required
|
||||
/// by the protocol.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_set_our_htlc_minimum_msat(this_ptr: &mut ChannelHandshakeConfig, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.our_htlc_minimum_msat = val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_new(mut minimum_depth_arg: u32, mut our_to_self_delay_arg: u16, mut our_htlc_minimum_msat_arg: u64) -> ChannelHandshakeConfig {
|
||||
ChannelHandshakeConfig { inner: Box::into_raw(Box::new(nativeChannelHandshakeConfig {
|
||||
minimum_depth: minimum_depth_arg,
|
||||
our_to_self_delay: our_to_self_delay_arg,
|
||||
our_htlc_minimum_msat: our_htlc_minimum_msat_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeConfig_default() -> ChannelHandshakeConfig {
|
||||
ChannelHandshakeConfig { inner: Box::into_raw(Box::new(Default::default())), is_owned: true }
|
||||
}
|
||||
|
||||
use lightning::util::config::ChannelHandshakeLimits as nativeChannelHandshakeLimitsImport;
|
||||
type nativeChannelHandshakeLimits = nativeChannelHandshakeLimitsImport;
|
||||
|
||||
/// Optional channel limits which are applied during channel creation.
|
||||
///
|
||||
/// These limits are only applied to our counterparty's limits, not our own.
|
||||
///
|
||||
/// Use 0/<type>::max_value() as appropriate to skip checking.
|
||||
///
|
||||
/// Provides sane defaults for most configurations.
|
||||
///
|
||||
/// Most additional limits are disabled except those with which specify a default in individual
|
||||
/// field documentation. Note that this may result in barely-usable channels, but since they
|
||||
/// are applied mostly only to incoming channels that's not much of a problem.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelHandshakeLimits {
|
||||
/// Nearly everyhwere, 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 nativeChannelHandshakeLimits,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelHandshakeLimits {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_free(this_ptr: ChannelHandshakeLimits) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelHandshakeLimits_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelHandshakeLimits); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelHandshakeLimits {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelHandshakeLimits {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for ChannelHandshakeLimits {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn ChannelHandshakeLimits_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelHandshakeLimits)).clone() })) as *mut c_void
|
||||
}
|
||||
/// Minimum allowed satoshis when a channel is funded, this is supplied by the sender and so
|
||||
/// only applies to inbound channels.
|
||||
///
|
||||
/// Default value: 0.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_min_funding_satoshis(this_ptr: &ChannelHandshakeLimits) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.min_funding_satoshis;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Minimum allowed satoshis when a channel is funded, this is supplied by the sender and so
|
||||
/// only applies to inbound channels.
|
||||
///
|
||||
/// Default value: 0.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_min_funding_satoshis(this_ptr: &mut ChannelHandshakeLimits, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.min_funding_satoshis = val;
|
||||
}
|
||||
/// The remote node sets a limit on the minimum size of HTLCs we can send to them. This allows
|
||||
/// you to limit the maximum minimum-size they can require.
|
||||
///
|
||||
/// Default value: u64::max_value.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_max_htlc_minimum_msat(this_ptr: &ChannelHandshakeLimits) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.max_htlc_minimum_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The remote node sets a limit on the minimum size of HTLCs we can send to them. This allows
|
||||
/// you to limit the maximum minimum-size they can require.
|
||||
///
|
||||
/// Default value: u64::max_value.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_max_htlc_minimum_msat(this_ptr: &mut ChannelHandshakeLimits, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.max_htlc_minimum_msat = val;
|
||||
}
|
||||
/// The remote node sets a limit on the maximum value of pending HTLCs to them at any given
|
||||
/// time to limit their funds exposure to HTLCs. This allows you to set a minimum such value.
|
||||
///
|
||||
/// Default value: 0.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_min_max_htlc_value_in_flight_msat(this_ptr: &ChannelHandshakeLimits) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.min_max_htlc_value_in_flight_msat;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The remote node sets a limit on the maximum value of pending HTLCs to them at any given
|
||||
/// time to limit their funds exposure to HTLCs. This allows you to set a minimum such value.
|
||||
///
|
||||
/// Default value: 0.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_min_max_htlc_value_in_flight_msat(this_ptr: &mut ChannelHandshakeLimits, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.min_max_htlc_value_in_flight_msat = val;
|
||||
}
|
||||
/// The remote node will require we keep a certain amount in direct payment to ourselves at all
|
||||
/// time, ensuring that we are able to be punished if we broadcast an old state. This allows to
|
||||
/// you limit the amount which we will have to keep to ourselves (and cannot use for HTLCs).
|
||||
///
|
||||
/// Default value: u64::max_value.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_max_channel_reserve_satoshis(this_ptr: &ChannelHandshakeLimits) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.max_channel_reserve_satoshis;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The remote node will require we keep a certain amount in direct payment to ourselves at all
|
||||
/// time, ensuring that we are able to be punished if we broadcast an old state. This allows to
|
||||
/// you limit the amount which we will have to keep to ourselves (and cannot use for HTLCs).
|
||||
///
|
||||
/// Default value: u64::max_value.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_max_channel_reserve_satoshis(this_ptr: &mut ChannelHandshakeLimits, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.max_channel_reserve_satoshis = val;
|
||||
}
|
||||
/// The remote node sets a limit on the maximum number of pending HTLCs to them at any given
|
||||
/// time. This allows you to set a minimum such value.
|
||||
///
|
||||
/// Default value: 0.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_min_max_accepted_htlcs(this_ptr: &ChannelHandshakeLimits) -> u16 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.min_max_accepted_htlcs;
|
||||
(*inner_val)
|
||||
}
|
||||
/// The remote node sets a limit on the maximum number of pending HTLCs to them at any given
|
||||
/// time. This allows you to set a minimum such value.
|
||||
///
|
||||
/// Default value: 0.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_min_max_accepted_htlcs(this_ptr: &mut ChannelHandshakeLimits, mut val: u16) {
|
||||
unsafe { &mut *this_ptr.inner }.min_max_accepted_htlcs = val;
|
||||
}
|
||||
/// Outputs below a certain value will not be added to on-chain transactions. The dust value is
|
||||
/// required to always be higher than this value so this only applies to HTLC outputs (and
|
||||
/// potentially to-self outputs before any payments have been made).
|
||||
/// Thus, HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain.
|
||||
/// This setting allows you to set a minimum dust limit for their commitment transactions,
|
||||
/// reflecting the reality that tiny outputs are not considered standard transactions and will
|
||||
/// not propagate through the Bitcoin network.
|
||||
///
|
||||
/// Default value: 546, the current dust limit on the Bitcoin network.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_min_dust_limit_satoshis(this_ptr: &ChannelHandshakeLimits) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.min_dust_limit_satoshis;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Outputs below a certain value will not be added to on-chain transactions. The dust value is
|
||||
/// required to always be higher than this value so this only applies to HTLC outputs (and
|
||||
/// potentially to-self outputs before any payments have been made).
|
||||
/// Thus, HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain.
|
||||
/// This setting allows you to set a minimum dust limit for their commitment transactions,
|
||||
/// reflecting the reality that tiny outputs are not considered standard transactions and will
|
||||
/// not propagate through the Bitcoin network.
|
||||
///
|
||||
/// Default value: 546, the current dust limit on the Bitcoin network.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_min_dust_limit_satoshis(this_ptr: &mut ChannelHandshakeLimits, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.min_dust_limit_satoshis = val;
|
||||
}
|
||||
/// Maximum allowed threshold above which outputs will not be generated in their commitment
|
||||
/// transactions.
|
||||
/// HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain.
|
||||
///
|
||||
/// Default value: u64::max_value.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_max_dust_limit_satoshis(this_ptr: &ChannelHandshakeLimits) -> u64 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.max_dust_limit_satoshis;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Maximum allowed threshold above which outputs will not be generated in their commitment
|
||||
/// transactions.
|
||||
/// HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain.
|
||||
///
|
||||
/// Default value: u64::max_value.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_max_dust_limit_satoshis(this_ptr: &mut ChannelHandshakeLimits, mut val: u64) {
|
||||
unsafe { &mut *this_ptr.inner }.max_dust_limit_satoshis = val;
|
||||
}
|
||||
/// Before a channel is usable the funding transaction will need to be confirmed by at least a
|
||||
/// certain number of blocks, specified by the node which is not the funder (as the funder can
|
||||
/// assume they aren't going to double-spend themselves).
|
||||
/// This config allows you to set a limit on the maximum amount of time to wait.
|
||||
///
|
||||
/// Default value: 144, or roughly one day and only applies to outbound channels.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_max_minimum_depth(this_ptr: &ChannelHandshakeLimits) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.max_minimum_depth;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Before a channel is usable the funding transaction will need to be confirmed by at least a
|
||||
/// certain number of blocks, specified by the node which is not the funder (as the funder can
|
||||
/// assume they aren't going to double-spend themselves).
|
||||
/// This config allows you to set a limit on the maximum amount of time to wait.
|
||||
///
|
||||
/// Default value: 144, or roughly one day and only applies to outbound channels.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_max_minimum_depth(this_ptr: &mut ChannelHandshakeLimits, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.max_minimum_depth = val;
|
||||
}
|
||||
/// Set to force the incoming channel to match our announced channel preference in
|
||||
/// ChannelConfig.
|
||||
///
|
||||
/// Default value: true, to make the default that no announced channels are possible (which is
|
||||
/// appropriate for any nodes which are not online very reliably).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_force_announced_channel_preference(this_ptr: &ChannelHandshakeLimits) -> bool {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.force_announced_channel_preference;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Set to force the incoming channel to match our announced channel preference in
|
||||
/// ChannelConfig.
|
||||
///
|
||||
/// Default value: true, to make the default that no announced channels are possible (which is
|
||||
/// appropriate for any nodes which are not online very reliably).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_force_announced_channel_preference(this_ptr: &mut ChannelHandshakeLimits, mut val: bool) {
|
||||
unsafe { &mut *this_ptr.inner }.force_announced_channel_preference = val;
|
||||
}
|
||||
/// Set to the amount of time we're willing to wait to claim money back to us.
|
||||
///
|
||||
/// Not checking this value would be a security issue, as our peer would be able to set it to
|
||||
/// max relative lock-time (a year) and we would \"lose\" money as it would be locked for a long time.
|
||||
///
|
||||
/// Default value: MAX_LOCAL_BREAKDOWN_TIMEOUT (1008), which we also enforce as a maximum value
|
||||
/// so you can tweak config to reduce the loss of having useless locked funds (if your peer accepts)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_get_their_to_self_delay(this_ptr: &ChannelHandshakeLimits) -> u16 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.their_to_self_delay;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Set to the amount of time we're willing to wait to claim money back to us.
|
||||
///
|
||||
/// Not checking this value would be a security issue, as our peer would be able to set it to
|
||||
/// max relative lock-time (a year) and we would \"lose\" money as it would be locked for a long time.
|
||||
///
|
||||
/// Default value: MAX_LOCAL_BREAKDOWN_TIMEOUT (1008), which we also enforce as a maximum value
|
||||
/// so you can tweak config to reduce the loss of having useless locked funds (if your peer accepts)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_set_their_to_self_delay(this_ptr: &mut ChannelHandshakeLimits, mut val: u16) {
|
||||
unsafe { &mut *this_ptr.inner }.their_to_self_delay = val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_new(mut min_funding_satoshis_arg: u64, mut max_htlc_minimum_msat_arg: u64, mut min_max_htlc_value_in_flight_msat_arg: u64, mut max_channel_reserve_satoshis_arg: u64, mut min_max_accepted_htlcs_arg: u16, mut min_dust_limit_satoshis_arg: u64, mut max_dust_limit_satoshis_arg: u64, mut max_minimum_depth_arg: u32, mut force_announced_channel_preference_arg: bool, mut their_to_self_delay_arg: u16) -> ChannelHandshakeLimits {
|
||||
ChannelHandshakeLimits { inner: Box::into_raw(Box::new(nativeChannelHandshakeLimits {
|
||||
min_funding_satoshis: min_funding_satoshis_arg,
|
||||
max_htlc_minimum_msat: max_htlc_minimum_msat_arg,
|
||||
min_max_htlc_value_in_flight_msat: min_max_htlc_value_in_flight_msat_arg,
|
||||
max_channel_reserve_satoshis: max_channel_reserve_satoshis_arg,
|
||||
min_max_accepted_htlcs: min_max_accepted_htlcs_arg,
|
||||
min_dust_limit_satoshis: min_dust_limit_satoshis_arg,
|
||||
max_dust_limit_satoshis: max_dust_limit_satoshis_arg,
|
||||
max_minimum_depth: max_minimum_depth_arg,
|
||||
force_announced_channel_preference: force_announced_channel_preference_arg,
|
||||
their_to_self_delay: their_to_self_delay_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelHandshakeLimits_default() -> ChannelHandshakeLimits {
|
||||
ChannelHandshakeLimits { inner: Box::into_raw(Box::new(Default::default())), is_owned: true }
|
||||
}
|
||||
|
||||
use lightning::util::config::ChannelConfig as nativeChannelConfigImport;
|
||||
type nativeChannelConfig = nativeChannelConfigImport;
|
||||
|
||||
/// Options which apply on a per-channel basis and may change at runtime or based on negotiation
|
||||
/// with our counterparty.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct ChannelConfig {
|
||||
/// Nearly everyhwere, 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 nativeChannelConfig,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for ChannelConfig {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_free(this_ptr: ChannelConfig) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn ChannelConfig_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelConfig); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl ChannelConfig {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeChannelConfig {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for ChannelConfig {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn ChannelConfig_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelConfig)).clone() })) as *mut c_void
|
||||
}
|
||||
/// Amount (in millionths of a satoshi) the channel will charge per transferred satoshi.
|
||||
/// This may be allowed to change at runtime in a later update, however doing so must result in
|
||||
/// update messages sent to notify all nodes of our updated relay fee.
|
||||
///
|
||||
/// Default value: 0.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_get_fee_proportional_millionths(this_ptr: &ChannelConfig) -> u32 {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.fee_proportional_millionths;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Amount (in millionths of a satoshi) the channel will charge per transferred satoshi.
|
||||
/// This may be allowed to change at runtime in a later update, however doing so must result in
|
||||
/// update messages sent to notify all nodes of our updated relay fee.
|
||||
///
|
||||
/// Default value: 0.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_set_fee_proportional_millionths(this_ptr: &mut ChannelConfig, mut val: u32) {
|
||||
unsafe { &mut *this_ptr.inner }.fee_proportional_millionths = val;
|
||||
}
|
||||
/// Set to announce the channel publicly and notify all nodes that they can route via this
|
||||
/// channel.
|
||||
///
|
||||
/// This should only be set to true for nodes which expect to be online reliably.
|
||||
///
|
||||
/// As the node which funds a channel picks this value this will only apply for new outbound
|
||||
/// channels unless ChannelHandshakeLimits::force_announced_channel_preferences is set.
|
||||
///
|
||||
/// This cannot be changed after the initial channel handshake.
|
||||
///
|
||||
/// Default value: false.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_get_announced_channel(this_ptr: &ChannelConfig) -> bool {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.announced_channel;
|
||||
(*inner_val)
|
||||
}
|
||||
/// Set to announce the channel publicly and notify all nodes that they can route via this
|
||||
/// channel.
|
||||
///
|
||||
/// This should only be set to true for nodes which expect to be online reliably.
|
||||
///
|
||||
/// As the node which funds a channel picks this value this will only apply for new outbound
|
||||
/// channels unless ChannelHandshakeLimits::force_announced_channel_preferences is set.
|
||||
///
|
||||
/// This cannot be changed after the initial channel handshake.
|
||||
///
|
||||
/// Default value: false.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_set_announced_channel(this_ptr: &mut ChannelConfig, mut val: bool) {
|
||||
unsafe { &mut *this_ptr.inner }.announced_channel = val;
|
||||
}
|
||||
/// When set, we commit to an upfront shutdown_pubkey at channel open. If our counterparty
|
||||
/// supports it, they will then enforce the mutual-close output to us matches what we provided
|
||||
/// at intialization, preventing us from closing to an alternate pubkey.
|
||||
///
|
||||
/// This is set to true by default to provide a slight increase in security, though ultimately
|
||||
/// any attacker who is able to take control of a channel can just as easily send the funds via
|
||||
/// lightning payments, so we never require that our counterparties support this option.
|
||||
///
|
||||
/// This cannot be changed after a channel has been initialized.
|
||||
///
|
||||
/// Default value: true.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_get_commit_upfront_shutdown_pubkey(this_ptr: &ChannelConfig) -> bool {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.commit_upfront_shutdown_pubkey;
|
||||
(*inner_val)
|
||||
}
|
||||
/// When set, we commit to an upfront shutdown_pubkey at channel open. If our counterparty
|
||||
/// supports it, they will then enforce the mutual-close output to us matches what we provided
|
||||
/// at intialization, preventing us from closing to an alternate pubkey.
|
||||
///
|
||||
/// This is set to true by default to provide a slight increase in security, though ultimately
|
||||
/// any attacker who is able to take control of a channel can just as easily send the funds via
|
||||
/// lightning payments, so we never require that our counterparties support this option.
|
||||
///
|
||||
/// This cannot be changed after a channel has been initialized.
|
||||
///
|
||||
/// Default value: true.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_set_commit_upfront_shutdown_pubkey(this_ptr: &mut ChannelConfig, mut val: bool) {
|
||||
unsafe { &mut *this_ptr.inner }.commit_upfront_shutdown_pubkey = val;
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_new(mut fee_proportional_millionths_arg: u32, mut announced_channel_arg: bool, mut commit_upfront_shutdown_pubkey_arg: bool) -> ChannelConfig {
|
||||
ChannelConfig { inner: Box::into_raw(Box::new(nativeChannelConfig {
|
||||
fee_proportional_millionths: fee_proportional_millionths_arg,
|
||||
announced_channel: announced_channel_arg,
|
||||
commit_upfront_shutdown_pubkey: commit_upfront_shutdown_pubkey_arg,
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_default() -> ChannelConfig {
|
||||
ChannelConfig { inner: Box::into_raw(Box::new(Default::default())), is_owned: true }
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_write(obj: *const ChannelConfig) -> crate::c_types::derived::CVec_u8Z {
|
||||
crate::c_types::serialize_obj(unsafe { &(*(*obj).inner) })
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ChannelConfig_read(ser: crate::c_types::u8slice) -> ChannelConfig {
|
||||
if let Ok(res) = crate::c_types::deserialize_obj(ser) {
|
||||
ChannelConfig { inner: Box::into_raw(Box::new(res)), is_owned: true }
|
||||
} else {
|
||||
ChannelConfig { inner: std::ptr::null_mut(), is_owned: true }
|
||||
}
|
||||
}
|
||||
|
||||
use lightning::util::config::UserConfig as nativeUserConfigImport;
|
||||
type nativeUserConfig = nativeUserConfigImport;
|
||||
|
||||
/// Top-level config which holds ChannelHandshakeLimits and ChannelConfig.
|
||||
///
|
||||
/// Default::default() provides sane defaults for most configurations
|
||||
/// (but currently with 0 relay fees!)
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct UserConfig {
|
||||
/// Nearly everyhwere, 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 nativeUserConfig,
|
||||
pub is_owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for UserConfig {
|
||||
fn drop(&mut self) {
|
||||
if self.is_owned && !self.inner.is_null() {
|
||||
let _ = unsafe { Box::from_raw(self.inner) };
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_free(this_ptr: UserConfig) { }
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
extern "C" fn UserConfig_free_void(this_ptr: *mut c_void) {
|
||||
unsafe { let _ = Box::from_raw(this_ptr as *mut nativeUserConfig); }
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
|
||||
impl UserConfig {
|
||||
pub(crate) fn take_ptr(mut self) -> *mut nativeUserConfig {
|
||||
assert!(self.is_owned);
|
||||
let ret = self.inner;
|
||||
self.inner = std::ptr::null_mut();
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl Clone for UserConfig {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Box::into_raw(Box::new(unsafe { &*self.inner }.clone())),
|
||||
is_owned: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
/// Used only if an object of this type is returned as a trait impl by a method
|
||||
pub(crate) extern "C" fn UserConfig_clone_void(this_ptr: *const c_void) -> *mut c_void {
|
||||
Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeUserConfig)).clone() })) as *mut c_void
|
||||
}
|
||||
/// Channel config that we propose to our counterparty.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_get_own_channel_config(this_ptr: &UserConfig) -> crate::util::config::ChannelHandshakeConfig {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.own_channel_config;
|
||||
crate::util::config::ChannelHandshakeConfig { inner: unsafe { ( (&((*inner_val)) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
/// Channel config that we propose to our counterparty.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_set_own_channel_config(this_ptr: &mut UserConfig, mut val: crate::util::config::ChannelHandshakeConfig) {
|
||||
unsafe { &mut *this_ptr.inner }.own_channel_config = *unsafe { Box::from_raw(val.take_ptr()) };
|
||||
}
|
||||
/// Limits applied to our counterparty's proposed channel config settings.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_get_peer_channel_config_limits(this_ptr: &UserConfig) -> crate::util::config::ChannelHandshakeLimits {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.peer_channel_config_limits;
|
||||
crate::util::config::ChannelHandshakeLimits { inner: unsafe { ( (&((*inner_val)) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
/// Limits applied to our counterparty's proposed channel config settings.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_set_peer_channel_config_limits(this_ptr: &mut UserConfig, mut val: crate::util::config::ChannelHandshakeLimits) {
|
||||
unsafe { &mut *this_ptr.inner }.peer_channel_config_limits = *unsafe { Box::from_raw(val.take_ptr()) };
|
||||
}
|
||||
/// Channel config which affects behavior during channel lifetime.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_get_channel_options(this_ptr: &UserConfig) -> crate::util::config::ChannelConfig {
|
||||
let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.channel_options;
|
||||
crate::util::config::ChannelConfig { inner: unsafe { ( (&((*inner_val)) as *const _) as *mut _) }, is_owned: false }
|
||||
}
|
||||
/// Channel config which affects behavior during channel lifetime.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_set_channel_options(this_ptr: &mut UserConfig, mut val: crate::util::config::ChannelConfig) {
|
||||
unsafe { &mut *this_ptr.inner }.channel_options = *unsafe { Box::from_raw(val.take_ptr()) };
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_new(mut own_channel_config_arg: crate::util::config::ChannelHandshakeConfig, mut peer_channel_config_limits_arg: crate::util::config::ChannelHandshakeLimits, mut channel_options_arg: crate::util::config::ChannelConfig) -> UserConfig {
|
||||
UserConfig { inner: Box::into_raw(Box::new(nativeUserConfig {
|
||||
own_channel_config: *unsafe { Box::from_raw(own_channel_config_arg.take_ptr()) },
|
||||
peer_channel_config_limits: *unsafe { Box::from_raw(peer_channel_config_limits_arg.take_ptr()) },
|
||||
channel_options: *unsafe { Box::from_raw(channel_options_arg.take_ptr()) },
|
||||
})), is_owned: true }
|
||||
}
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn UserConfig_default() -> UserConfig {
|
||||
UserConfig { inner: Box::into_raw(Box::new(Default::default())), is_owned: true }
|
||||
}
|
162
lightning-c-bindings/src/util/errors.rs
Normal file
162
lightning-c-bindings/src/util/errors.rs
Normal file
|
@ -0,0 +1,162 @@
|
|||
//! Error types live here.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
/// Indicates an error on the client's part (usually some variant of attempting to use too-low or
|
||||
/// too-high values)
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub enum APIError {
|
||||
/// Indicates the API was wholly misused (see err for more). Cases where these can be returned
|
||||
/// are documented, but generally indicates some precondition of a function was violated.
|
||||
APIMisuseError {
|
||||
err: crate::c_types::derived::CVec_u8Z,
|
||||
},
|
||||
/// Due to a high feerate, we were unable to complete the request.
|
||||
/// For example, this may be returned if the feerate implies we cannot open a channel at the
|
||||
/// requested value, but opening a larger channel would succeed.
|
||||
FeeRateTooHigh {
|
||||
err: crate::c_types::derived::CVec_u8Z,
|
||||
feerate: u32,
|
||||
},
|
||||
/// A malformed Route was provided (eg overflowed value, node id mismatch, overly-looped route,
|
||||
/// too-many-hops, etc).
|
||||
RouteError {
|
||||
err: crate::c_types::Str,
|
||||
},
|
||||
/// We were unable to complete the request as the Channel required to do so is unable to
|
||||
/// complete the request (or was not found). This can take many forms, including disconnected
|
||||
/// peer, channel at capacity, channel shutting down, etc.
|
||||
ChannelUnavailable {
|
||||
err: crate::c_types::derived::CVec_u8Z,
|
||||
},
|
||||
/// An attempt to call add/update_monitor returned an Err (ie you did this!), causing the
|
||||
/// attempted action to fail.
|
||||
MonitorUpdateFailed,
|
||||
}
|
||||
use lightning::util::errors::APIError as nativeAPIError;
|
||||
impl APIError {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn to_native(&self) -> nativeAPIError {
|
||||
match self {
|
||||
APIError::APIMisuseError {ref err, } => {
|
||||
let mut err_nonref = (*err).clone();
|
||||
nativeAPIError::APIMisuseError {
|
||||
err: String::from_utf8(err_nonref.into_rust()).unwrap(),
|
||||
}
|
||||
},
|
||||
APIError::FeeRateTooHigh {ref err, ref feerate, } => {
|
||||
let mut err_nonref = (*err).clone();
|
||||
let mut feerate_nonref = (*feerate).clone();
|
||||
nativeAPIError::FeeRateTooHigh {
|
||||
err: String::from_utf8(err_nonref.into_rust()).unwrap(),
|
||||
feerate: feerate_nonref,
|
||||
}
|
||||
},
|
||||
APIError::RouteError {ref err, } => {
|
||||
let mut err_nonref = (*err).clone();
|
||||
nativeAPIError::RouteError {
|
||||
err: err_nonref.into(),
|
||||
}
|
||||
},
|
||||
APIError::ChannelUnavailable {ref err, } => {
|
||||
let mut err_nonref = (*err).clone();
|
||||
nativeAPIError::ChannelUnavailable {
|
||||
err: String::from_utf8(err_nonref.into_rust()).unwrap(),
|
||||
}
|
||||
},
|
||||
APIError::MonitorUpdateFailed => nativeAPIError::MonitorUpdateFailed,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn into_native(self) -> nativeAPIError {
|
||||
match self {
|
||||
APIError::APIMisuseError {mut err, } => {
|
||||
nativeAPIError::APIMisuseError {
|
||||
err: String::from_utf8(err.into_rust()).unwrap(),
|
||||
}
|
||||
},
|
||||
APIError::FeeRateTooHigh {mut err, mut feerate, } => {
|
||||
nativeAPIError::FeeRateTooHigh {
|
||||
err: String::from_utf8(err.into_rust()).unwrap(),
|
||||
feerate: feerate,
|
||||
}
|
||||
},
|
||||
APIError::RouteError {mut err, } => {
|
||||
nativeAPIError::RouteError {
|
||||
err: err.into(),
|
||||
}
|
||||
},
|
||||
APIError::ChannelUnavailable {mut err, } => {
|
||||
nativeAPIError::ChannelUnavailable {
|
||||
err: String::from_utf8(err.into_rust()).unwrap(),
|
||||
}
|
||||
},
|
||||
APIError::MonitorUpdateFailed => nativeAPIError::MonitorUpdateFailed,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn from_native(native: &nativeAPIError) -> Self {
|
||||
match native {
|
||||
nativeAPIError::APIMisuseError {ref err, } => {
|
||||
let mut err_nonref = (*err).clone();
|
||||
APIError::APIMisuseError {
|
||||
err: err_nonref.into_bytes().into(),
|
||||
}
|
||||
},
|
||||
nativeAPIError::FeeRateTooHigh {ref err, ref feerate, } => {
|
||||
let mut err_nonref = (*err).clone();
|
||||
let mut feerate_nonref = (*feerate).clone();
|
||||
APIError::FeeRateTooHigh {
|
||||
err: err_nonref.into_bytes().into(),
|
||||
feerate: feerate_nonref,
|
||||
}
|
||||
},
|
||||
nativeAPIError::RouteError {ref err, } => {
|
||||
let mut err_nonref = (*err).clone();
|
||||
APIError::RouteError {
|
||||
err: err_nonref.into(),
|
||||
}
|
||||
},
|
||||
nativeAPIError::ChannelUnavailable {ref err, } => {
|
||||
let mut err_nonref = (*err).clone();
|
||||
APIError::ChannelUnavailable {
|
||||
err: err_nonref.into_bytes().into(),
|
||||
}
|
||||
},
|
||||
nativeAPIError::MonitorUpdateFailed => APIError::MonitorUpdateFailed,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn native_into(native: nativeAPIError) -> Self {
|
||||
match native {
|
||||
nativeAPIError::APIMisuseError {mut err, } => {
|
||||
APIError::APIMisuseError {
|
||||
err: err.into_bytes().into(),
|
||||
}
|
||||
},
|
||||
nativeAPIError::FeeRateTooHigh {mut err, mut feerate, } => {
|
||||
APIError::FeeRateTooHigh {
|
||||
err: err.into_bytes().into(),
|
||||
feerate: feerate,
|
||||
}
|
||||
},
|
||||
nativeAPIError::RouteError {mut err, } => {
|
||||
APIError::RouteError {
|
||||
err: err.into(),
|
||||
}
|
||||
},
|
||||
nativeAPIError::ChannelUnavailable {mut err, } => {
|
||||
APIError::ChannelUnavailable {
|
||||
err: err.into_bytes().into(),
|
||||
}
|
||||
},
|
||||
nativeAPIError::MonitorUpdateFailed => APIError::MonitorUpdateFailed,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn APIError_free(this_ptr: APIError) { }
|
937
lightning-c-bindings/src/util/events.rs
Normal file
937
lightning-c-bindings/src/util/events.rs
Normal file
|
@ -0,0 +1,937 @@
|
|||
//! Events are returned from various bits in the library which indicate some action must be taken
|
||||
//! by the client.
|
||||
//!
|
||||
//! Because we don't have a built-in runtime, it's up to the client to call events at a time in the
|
||||
//! future, as well as generate and broadcast funding transactions handle payment preimages and a
|
||||
//! few other things.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
/// An Event which you should probably take some action in response to.
|
||||
///
|
||||
/// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
|
||||
/// them directly as they don't round-trip exactly (for example FundingGenerationReady is never
|
||||
/// written as it makes no sense to respond to it after reconnecting to peers).
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub enum Event {
|
||||
/// Used to indicate that the client should generate a funding transaction with the given
|
||||
/// parameters and then call ChannelManager::funding_transaction_generated.
|
||||
/// Generated in ChannelManager message handling.
|
||||
/// Note that *all inputs* in the funding transaction must spend SegWit outputs or your
|
||||
/// counterparty can steal your funds!
|
||||
FundingGenerationReady {
|
||||
temporary_channel_id: crate::c_types::ThirtyTwoBytes,
|
||||
channel_value_satoshis: u64,
|
||||
output_script: crate::c_types::derived::CVec_u8Z,
|
||||
user_channel_id: u64,
|
||||
},
|
||||
/// Used to indicate that the client may now broadcast the funding transaction it created for a
|
||||
/// channel. Broadcasting such a transaction prior to this event may lead to our counterparty
|
||||
/// trivially stealing all funds in the funding transaction!
|
||||
FundingBroadcastSafe {
|
||||
funding_txo: crate::chain::transaction::OutPoint,
|
||||
user_channel_id: u64,
|
||||
},
|
||||
/// Indicates we've received money! Just gotta dig out that payment preimage and feed it to
|
||||
/// ChannelManager::claim_funds to get it....
|
||||
/// Note that if the preimage is not known or the amount paid is incorrect, you should call
|
||||
/// ChannelManager::fail_htlc_backwards to free up resources for this HTLC and avoid
|
||||
/// network congestion.
|
||||
/// The amount paid should be considered 'incorrect' when it is less than or more than twice
|
||||
/// the amount expected.
|
||||
/// If you fail to call either ChannelManager::claim_funds or
|
||||
/// ChannelManager::fail_htlc_backwards within the HTLC's timeout, the HTLC will be
|
||||
/// automatically failed.
|
||||
PaymentReceived {
|
||||
payment_hash: crate::c_types::ThirtyTwoBytes,
|
||||
payment_secret: crate::c_types::ThirtyTwoBytes,
|
||||
amt: u64,
|
||||
},
|
||||
/// Indicates an outbound payment we made succeeded (ie it made it all the way to its target
|
||||
/// and we got back the payment preimage for it).
|
||||
/// Note that duplicative PaymentSent Events may be generated - it is your responsibility to
|
||||
/// deduplicate them by payment_preimage (which MUST be unique)!
|
||||
PaymentSent {
|
||||
payment_preimage: crate::c_types::ThirtyTwoBytes,
|
||||
},
|
||||
/// Indicates an outbound payment we made failed. Probably some intermediary node dropped
|
||||
/// something. You may wish to retry with a different route.
|
||||
/// Note that duplicative PaymentFailed Events may be generated - it is your responsibility to
|
||||
/// deduplicate them by payment_hash (which MUST be unique)!
|
||||
PaymentFailed {
|
||||
payment_hash: crate::c_types::ThirtyTwoBytes,
|
||||
rejected_by_dest: bool,
|
||||
},
|
||||
/// Used to indicate that ChannelManager::process_pending_htlc_forwards should be called at a
|
||||
/// time in the future.
|
||||
PendingHTLCsForwardable {
|
||||
time_forwardable: u64,
|
||||
},
|
||||
/// Used to indicate that an output was generated on-chain which you should know how to spend.
|
||||
/// Such an output will *not* ever be spent by rust-lightning, and are not at risk of your
|
||||
/// counterparty spending them due to some kind of timeout. Thus, you need to store them
|
||||
/// somewhere and spend them when you create on-chain transactions.
|
||||
SpendableOutputs {
|
||||
outputs: crate::c_types::derived::CVec_SpendableOutputDescriptorZ,
|
||||
},
|
||||
}
|
||||
use lightning::util::events::Event as nativeEvent;
|
||||
impl Event {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn to_native(&self) -> nativeEvent {
|
||||
match self {
|
||||
Event::FundingGenerationReady {ref temporary_channel_id, ref channel_value_satoshis, ref output_script, ref user_channel_id, } => {
|
||||
let mut temporary_channel_id_nonref = (*temporary_channel_id).clone();
|
||||
let mut channel_value_satoshis_nonref = (*channel_value_satoshis).clone();
|
||||
let mut output_script_nonref = (*output_script).clone();
|
||||
let mut user_channel_id_nonref = (*user_channel_id).clone();
|
||||
nativeEvent::FundingGenerationReady {
|
||||
temporary_channel_id: temporary_channel_id_nonref.data,
|
||||
channel_value_satoshis: channel_value_satoshis_nonref,
|
||||
output_script: ::bitcoin::blockdata::script::Script::from(output_script_nonref.into_rust()),
|
||||
user_channel_id: user_channel_id_nonref,
|
||||
}
|
||||
},
|
||||
Event::FundingBroadcastSafe {ref funding_txo, ref user_channel_id, } => {
|
||||
let mut funding_txo_nonref = (*funding_txo).clone();
|
||||
let mut user_channel_id_nonref = (*user_channel_id).clone();
|
||||
nativeEvent::FundingBroadcastSafe {
|
||||
funding_txo: *unsafe { Box::from_raw(funding_txo_nonref.take_ptr()) },
|
||||
user_channel_id: user_channel_id_nonref,
|
||||
}
|
||||
},
|
||||
Event::PaymentReceived {ref payment_hash, ref payment_secret, ref amt, } => {
|
||||
let mut payment_hash_nonref = (*payment_hash).clone();
|
||||
let mut payment_secret_nonref = (*payment_secret).clone();
|
||||
let mut local_payment_secret_nonref = if payment_secret_nonref.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret_nonref.data) }) };
|
||||
let mut amt_nonref = (*amt).clone();
|
||||
nativeEvent::PaymentReceived {
|
||||
payment_hash: ::lightning::ln::channelmanager::PaymentHash(payment_hash_nonref.data),
|
||||
payment_secret: local_payment_secret_nonref,
|
||||
amt: amt_nonref,
|
||||
}
|
||||
},
|
||||
Event::PaymentSent {ref payment_preimage, } => {
|
||||
let mut payment_preimage_nonref = (*payment_preimage).clone();
|
||||
nativeEvent::PaymentSent {
|
||||
payment_preimage: ::lightning::ln::channelmanager::PaymentPreimage(payment_preimage_nonref.data),
|
||||
}
|
||||
},
|
||||
Event::PaymentFailed {ref payment_hash, ref rejected_by_dest, } => {
|
||||
let mut payment_hash_nonref = (*payment_hash).clone();
|
||||
let mut rejected_by_dest_nonref = (*rejected_by_dest).clone();
|
||||
nativeEvent::PaymentFailed {
|
||||
payment_hash: ::lightning::ln::channelmanager::PaymentHash(payment_hash_nonref.data),
|
||||
rejected_by_dest: rejected_by_dest_nonref,
|
||||
}
|
||||
},
|
||||
Event::PendingHTLCsForwardable {ref time_forwardable, } => {
|
||||
let mut time_forwardable_nonref = (*time_forwardable).clone();
|
||||
nativeEvent::PendingHTLCsForwardable {
|
||||
time_forwardable: std::time::Duration::from_secs(time_forwardable_nonref),
|
||||
}
|
||||
},
|
||||
Event::SpendableOutputs {ref outputs, } => {
|
||||
let mut outputs_nonref = (*outputs).clone();
|
||||
let mut local_outputs_nonref = Vec::new(); for mut item in outputs_nonref.into_rust().drain(..) { local_outputs_nonref.push( { item.into_native() }); };
|
||||
nativeEvent::SpendableOutputs {
|
||||
outputs: local_outputs_nonref,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn into_native(self) -> nativeEvent {
|
||||
match self {
|
||||
Event::FundingGenerationReady {mut temporary_channel_id, mut channel_value_satoshis, mut output_script, mut user_channel_id, } => {
|
||||
nativeEvent::FundingGenerationReady {
|
||||
temporary_channel_id: temporary_channel_id.data,
|
||||
channel_value_satoshis: channel_value_satoshis,
|
||||
output_script: ::bitcoin::blockdata::script::Script::from(output_script.into_rust()),
|
||||
user_channel_id: user_channel_id,
|
||||
}
|
||||
},
|
||||
Event::FundingBroadcastSafe {mut funding_txo, mut user_channel_id, } => {
|
||||
nativeEvent::FundingBroadcastSafe {
|
||||
funding_txo: *unsafe { Box::from_raw(funding_txo.take_ptr()) },
|
||||
user_channel_id: user_channel_id,
|
||||
}
|
||||
},
|
||||
Event::PaymentReceived {mut payment_hash, mut payment_secret, mut amt, } => {
|
||||
let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret.data) }) };
|
||||
nativeEvent::PaymentReceived {
|
||||
payment_hash: ::lightning::ln::channelmanager::PaymentHash(payment_hash.data),
|
||||
payment_secret: local_payment_secret,
|
||||
amt: amt,
|
||||
}
|
||||
},
|
||||
Event::PaymentSent {mut payment_preimage, } => {
|
||||
nativeEvent::PaymentSent {
|
||||
payment_preimage: ::lightning::ln::channelmanager::PaymentPreimage(payment_preimage.data),
|
||||
}
|
||||
},
|
||||
Event::PaymentFailed {mut payment_hash, mut rejected_by_dest, } => {
|
||||
nativeEvent::PaymentFailed {
|
||||
payment_hash: ::lightning::ln::channelmanager::PaymentHash(payment_hash.data),
|
||||
rejected_by_dest: rejected_by_dest,
|
||||
}
|
||||
},
|
||||
Event::PendingHTLCsForwardable {mut time_forwardable, } => {
|
||||
nativeEvent::PendingHTLCsForwardable {
|
||||
time_forwardable: std::time::Duration::from_secs(time_forwardable),
|
||||
}
|
||||
},
|
||||
Event::SpendableOutputs {mut outputs, } => {
|
||||
let mut local_outputs = Vec::new(); for mut item in outputs.into_rust().drain(..) { local_outputs.push( { item.into_native() }); };
|
||||
nativeEvent::SpendableOutputs {
|
||||
outputs: local_outputs,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn from_native(native: &nativeEvent) -> Self {
|
||||
match native {
|
||||
nativeEvent::FundingGenerationReady {ref temporary_channel_id, ref channel_value_satoshis, ref output_script, ref user_channel_id, } => {
|
||||
let mut temporary_channel_id_nonref = (*temporary_channel_id).clone();
|
||||
let mut channel_value_satoshis_nonref = (*channel_value_satoshis).clone();
|
||||
let mut output_script_nonref = (*output_script).clone();
|
||||
let mut user_channel_id_nonref = (*user_channel_id).clone();
|
||||
Event::FundingGenerationReady {
|
||||
temporary_channel_id: crate::c_types::ThirtyTwoBytes { data: temporary_channel_id_nonref },
|
||||
channel_value_satoshis: channel_value_satoshis_nonref,
|
||||
output_script: output_script_nonref.into_bytes().into(),
|
||||
user_channel_id: user_channel_id_nonref,
|
||||
}
|
||||
},
|
||||
nativeEvent::FundingBroadcastSafe {ref funding_txo, ref user_channel_id, } => {
|
||||
let mut funding_txo_nonref = (*funding_txo).clone();
|
||||
let mut user_channel_id_nonref = (*user_channel_id).clone();
|
||||
Event::FundingBroadcastSafe {
|
||||
funding_txo: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(funding_txo_nonref)), is_owned: true },
|
||||
user_channel_id: user_channel_id_nonref,
|
||||
}
|
||||
},
|
||||
nativeEvent::PaymentReceived {ref payment_hash, ref payment_secret, ref amt, } => {
|
||||
let mut payment_hash_nonref = (*payment_hash).clone();
|
||||
let mut payment_secret_nonref = (*payment_secret).clone();
|
||||
let mut local_payment_secret_nonref = if payment_secret_nonref.is_none() { crate::c_types::ThirtyTwoBytes::null() } else { { crate::c_types::ThirtyTwoBytes { data: (payment_secret_nonref.unwrap()).0 } } };
|
||||
let mut amt_nonref = (*amt).clone();
|
||||
Event::PaymentReceived {
|
||||
payment_hash: crate::c_types::ThirtyTwoBytes { data: payment_hash_nonref.0 },
|
||||
payment_secret: local_payment_secret_nonref,
|
||||
amt: amt_nonref,
|
||||
}
|
||||
},
|
||||
nativeEvent::PaymentSent {ref payment_preimage, } => {
|
||||
let mut payment_preimage_nonref = (*payment_preimage).clone();
|
||||
Event::PaymentSent {
|
||||
payment_preimage: crate::c_types::ThirtyTwoBytes { data: payment_preimage_nonref.0 },
|
||||
}
|
||||
},
|
||||
nativeEvent::PaymentFailed {ref payment_hash, ref rejected_by_dest, } => {
|
||||
let mut payment_hash_nonref = (*payment_hash).clone();
|
||||
let mut rejected_by_dest_nonref = (*rejected_by_dest).clone();
|
||||
Event::PaymentFailed {
|
||||
payment_hash: crate::c_types::ThirtyTwoBytes { data: payment_hash_nonref.0 },
|
||||
rejected_by_dest: rejected_by_dest_nonref,
|
||||
}
|
||||
},
|
||||
nativeEvent::PendingHTLCsForwardable {ref time_forwardable, } => {
|
||||
let mut time_forwardable_nonref = (*time_forwardable).clone();
|
||||
Event::PendingHTLCsForwardable {
|
||||
time_forwardable: time_forwardable_nonref.as_secs(),
|
||||
}
|
||||
},
|
||||
nativeEvent::SpendableOutputs {ref outputs, } => {
|
||||
let mut outputs_nonref = (*outputs).clone();
|
||||
let mut local_outputs_nonref = Vec::new(); for item in outputs_nonref.drain(..) { local_outputs_nonref.push( { crate::chain::keysinterface::SpendableOutputDescriptor::native_into(item) }); };
|
||||
Event::SpendableOutputs {
|
||||
outputs: local_outputs_nonref.into(),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn native_into(native: nativeEvent) -> Self {
|
||||
match native {
|
||||
nativeEvent::FundingGenerationReady {mut temporary_channel_id, mut channel_value_satoshis, mut output_script, mut user_channel_id, } => {
|
||||
Event::FundingGenerationReady {
|
||||
temporary_channel_id: crate::c_types::ThirtyTwoBytes { data: temporary_channel_id },
|
||||
channel_value_satoshis: channel_value_satoshis,
|
||||
output_script: output_script.into_bytes().into(),
|
||||
user_channel_id: user_channel_id,
|
||||
}
|
||||
},
|
||||
nativeEvent::FundingBroadcastSafe {mut funding_txo, mut user_channel_id, } => {
|
||||
Event::FundingBroadcastSafe {
|
||||
funding_txo: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(funding_txo)), is_owned: true },
|
||||
user_channel_id: user_channel_id,
|
||||
}
|
||||
},
|
||||
nativeEvent::PaymentReceived {mut payment_hash, mut payment_secret, mut amt, } => {
|
||||
let mut local_payment_secret = if payment_secret.is_none() { crate::c_types::ThirtyTwoBytes::null() } else { { crate::c_types::ThirtyTwoBytes { data: (payment_secret.unwrap()).0 } } };
|
||||
Event::PaymentReceived {
|
||||
payment_hash: crate::c_types::ThirtyTwoBytes { data: payment_hash.0 },
|
||||
payment_secret: local_payment_secret,
|
||||
amt: amt,
|
||||
}
|
||||
},
|
||||
nativeEvent::PaymentSent {mut payment_preimage, } => {
|
||||
Event::PaymentSent {
|
||||
payment_preimage: crate::c_types::ThirtyTwoBytes { data: payment_preimage.0 },
|
||||
}
|
||||
},
|
||||
nativeEvent::PaymentFailed {mut payment_hash, mut rejected_by_dest, } => {
|
||||
Event::PaymentFailed {
|
||||
payment_hash: crate::c_types::ThirtyTwoBytes { data: payment_hash.0 },
|
||||
rejected_by_dest: rejected_by_dest,
|
||||
}
|
||||
},
|
||||
nativeEvent::PendingHTLCsForwardable {mut time_forwardable, } => {
|
||||
Event::PendingHTLCsForwardable {
|
||||
time_forwardable: time_forwardable.as_secs(),
|
||||
}
|
||||
},
|
||||
nativeEvent::SpendableOutputs {mut outputs, } => {
|
||||
let mut local_outputs = Vec::new(); for item in outputs.drain(..) { local_outputs.push( { crate::chain::keysinterface::SpendableOutputDescriptor::native_into(item) }); };
|
||||
Event::SpendableOutputs {
|
||||
outputs: local_outputs.into(),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Event_free(this_ptr: Event) { }
|
||||
/// An event generated by ChannelManager which indicates a message should be sent to a peer (or
|
||||
/// broadcast to most peers).
|
||||
/// These events are handled by PeerManager::process_events if you are using a PeerManager.
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub enum MessageSendEvent {
|
||||
/// Used to indicate that we've accepted a channel open and should send the accept_channel
|
||||
/// message provided to the given peer.
|
||||
SendAcceptChannel {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::AcceptChannel,
|
||||
},
|
||||
/// Used to indicate that we've initiated a channel open and should send the open_channel
|
||||
/// message provided to the given peer.
|
||||
SendOpenChannel {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::OpenChannel,
|
||||
},
|
||||
/// Used to indicate that a funding_created message should be sent to the peer with the given node_id.
|
||||
SendFundingCreated {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::FundingCreated,
|
||||
},
|
||||
/// Used to indicate that a funding_signed message should be sent to the peer with the given node_id.
|
||||
SendFundingSigned {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::FundingSigned,
|
||||
},
|
||||
/// Used to indicate that a funding_locked message should be sent to the peer with the given node_id.
|
||||
SendFundingLocked {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::FundingLocked,
|
||||
},
|
||||
/// Used to indicate that an announcement_signatures message should be sent to the peer with the given node_id.
|
||||
SendAnnouncementSignatures {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::AnnouncementSignatures,
|
||||
},
|
||||
/// Used to indicate that a series of HTLC update messages, as well as a commitment_signed
|
||||
/// message should be sent to the peer with the given node_id.
|
||||
UpdateHTLCs {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
updates: crate::ln::msgs::CommitmentUpdate,
|
||||
},
|
||||
/// Used to indicate that a revoke_and_ack message should be sent to the peer with the given node_id.
|
||||
SendRevokeAndACK {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::RevokeAndACK,
|
||||
},
|
||||
/// Used to indicate that a closing_signed message should be sent to the peer with the given node_id.
|
||||
SendClosingSigned {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::ClosingSigned,
|
||||
},
|
||||
/// Used to indicate that a shutdown message should be sent to the peer with the given node_id.
|
||||
SendShutdown {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::Shutdown,
|
||||
},
|
||||
/// Used to indicate that a channel_reestablish message should be sent to the peer with the given node_id.
|
||||
SendChannelReestablish {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
msg: crate::ln::msgs::ChannelReestablish,
|
||||
},
|
||||
/// Used to indicate that a channel_announcement and channel_update should be broadcast to all
|
||||
/// peers (except the peer with node_id either msg.contents.node_id_1 or msg.contents.node_id_2).
|
||||
///
|
||||
/// Note that after doing so, you very likely (unless you did so very recently) want to call
|
||||
/// ChannelManager::broadcast_node_announcement to trigger a BroadcastNodeAnnouncement event.
|
||||
/// This ensures that any nodes which see our channel_announcement also have a relevant
|
||||
/// node_announcement, including relevant feature flags which may be important for routing
|
||||
/// through or to us.
|
||||
BroadcastChannelAnnouncement {
|
||||
msg: crate::ln::msgs::ChannelAnnouncement,
|
||||
update_msg: crate::ln::msgs::ChannelUpdate,
|
||||
},
|
||||
/// Used to indicate that a node_announcement should be broadcast to all peers.
|
||||
BroadcastNodeAnnouncement {
|
||||
msg: crate::ln::msgs::NodeAnnouncement,
|
||||
},
|
||||
/// Used to indicate that a channel_update should be broadcast to all peers.
|
||||
BroadcastChannelUpdate {
|
||||
msg: crate::ln::msgs::ChannelUpdate,
|
||||
},
|
||||
/// Broadcast an error downstream to be handled
|
||||
HandleError {
|
||||
node_id: crate::c_types::PublicKey,
|
||||
action: crate::ln::msgs::ErrorAction,
|
||||
},
|
||||
/// When a payment fails we may receive updates back from the hop where it failed. In such
|
||||
/// cases this event is generated so that we can inform the network graph of this information.
|
||||
PaymentFailureNetworkUpdate {
|
||||
update: crate::ln::msgs::HTLCFailChannelUpdate,
|
||||
},
|
||||
}
|
||||
use lightning::util::events::MessageSendEvent as nativeMessageSendEvent;
|
||||
impl MessageSendEvent {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn to_native(&self) -> nativeMessageSendEvent {
|
||||
match self {
|
||||
MessageSendEvent::SendAcceptChannel {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendAcceptChannel {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendOpenChannel {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendOpenChannel {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendFundingCreated {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendFundingCreated {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendFundingSigned {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendFundingSigned {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendFundingLocked {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendFundingLocked {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendAnnouncementSignatures {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendAnnouncementSignatures {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::UpdateHTLCs {ref node_id, ref updates, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut updates_nonref = (*updates).clone();
|
||||
nativeMessageSendEvent::UpdateHTLCs {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
updates: *unsafe { Box::from_raw(updates_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendRevokeAndACK {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendRevokeAndACK {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendClosingSigned {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendClosingSigned {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendShutdown {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendShutdown {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendChannelReestablish {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::SendChannelReestablish {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::BroadcastChannelAnnouncement {ref msg, ref update_msg, } => {
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
let mut update_msg_nonref = (*update_msg).clone();
|
||||
nativeMessageSendEvent::BroadcastChannelAnnouncement {
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
update_msg: *unsafe { Box::from_raw(update_msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::BroadcastNodeAnnouncement {ref msg, } => {
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::BroadcastNodeAnnouncement {
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::BroadcastChannelUpdate {ref msg, } => {
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
nativeMessageSendEvent::BroadcastChannelUpdate {
|
||||
msg: *unsafe { Box::from_raw(msg_nonref.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::HandleError {ref node_id, ref action, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut action_nonref = (*action).clone();
|
||||
nativeMessageSendEvent::HandleError {
|
||||
node_id: node_id_nonref.into_rust(),
|
||||
action: action_nonref.into_native(),
|
||||
}
|
||||
},
|
||||
MessageSendEvent::PaymentFailureNetworkUpdate {ref update, } => {
|
||||
let mut update_nonref = (*update).clone();
|
||||
nativeMessageSendEvent::PaymentFailureNetworkUpdate {
|
||||
update: update_nonref.into_native(),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn into_native(self) -> nativeMessageSendEvent {
|
||||
match self {
|
||||
MessageSendEvent::SendAcceptChannel {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendAcceptChannel {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendOpenChannel {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendOpenChannel {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendFundingCreated {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendFundingCreated {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendFundingSigned {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendFundingSigned {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendFundingLocked {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendFundingLocked {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendAnnouncementSignatures {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendAnnouncementSignatures {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::UpdateHTLCs {mut node_id, mut updates, } => {
|
||||
nativeMessageSendEvent::UpdateHTLCs {
|
||||
node_id: node_id.into_rust(),
|
||||
updates: *unsafe { Box::from_raw(updates.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendRevokeAndACK {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendRevokeAndACK {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendClosingSigned {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendClosingSigned {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendShutdown {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendShutdown {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::SendChannelReestablish {mut node_id, mut msg, } => {
|
||||
nativeMessageSendEvent::SendChannelReestablish {
|
||||
node_id: node_id.into_rust(),
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::BroadcastChannelAnnouncement {mut msg, mut update_msg, } => {
|
||||
nativeMessageSendEvent::BroadcastChannelAnnouncement {
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
update_msg: *unsafe { Box::from_raw(update_msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::BroadcastNodeAnnouncement {mut msg, } => {
|
||||
nativeMessageSendEvent::BroadcastNodeAnnouncement {
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::BroadcastChannelUpdate {mut msg, } => {
|
||||
nativeMessageSendEvent::BroadcastChannelUpdate {
|
||||
msg: *unsafe { Box::from_raw(msg.take_ptr()) },
|
||||
}
|
||||
},
|
||||
MessageSendEvent::HandleError {mut node_id, mut action, } => {
|
||||
nativeMessageSendEvent::HandleError {
|
||||
node_id: node_id.into_rust(),
|
||||
action: action.into_native(),
|
||||
}
|
||||
},
|
||||
MessageSendEvent::PaymentFailureNetworkUpdate {mut update, } => {
|
||||
nativeMessageSendEvent::PaymentFailureNetworkUpdate {
|
||||
update: update.into_native(),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn from_native(native: &nativeMessageSendEvent) -> Self {
|
||||
match native {
|
||||
nativeMessageSendEvent::SendAcceptChannel {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendAcceptChannel {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::AcceptChannel { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendOpenChannel {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendOpenChannel {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::OpenChannel { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendFundingCreated {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendFundingCreated {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::FundingCreated { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendFundingSigned {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendFundingSigned {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::FundingSigned { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendFundingLocked {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendFundingLocked {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::FundingLocked { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendAnnouncementSignatures {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendAnnouncementSignatures {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::AnnouncementSignatures { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::UpdateHTLCs {ref node_id, ref updates, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut updates_nonref = (*updates).clone();
|
||||
MessageSendEvent::UpdateHTLCs {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
updates: crate::ln::msgs::CommitmentUpdate { inner: Box::into_raw(Box::new(updates_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendRevokeAndACK {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendRevokeAndACK {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::RevokeAndACK { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendClosingSigned {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendClosingSigned {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::ClosingSigned { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendShutdown {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendShutdown {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::Shutdown { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendChannelReestablish {ref node_id, ref msg, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::SendChannelReestablish {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
msg: crate::ln::msgs::ChannelReestablish { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::BroadcastChannelAnnouncement {ref msg, ref update_msg, } => {
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
let mut update_msg_nonref = (*update_msg).clone();
|
||||
MessageSendEvent::BroadcastChannelAnnouncement {
|
||||
msg: crate::ln::msgs::ChannelAnnouncement { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
update_msg: crate::ln::msgs::ChannelUpdate { inner: Box::into_raw(Box::new(update_msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::BroadcastNodeAnnouncement {ref msg, } => {
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::BroadcastNodeAnnouncement {
|
||||
msg: crate::ln::msgs::NodeAnnouncement { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::BroadcastChannelUpdate {ref msg, } => {
|
||||
let mut msg_nonref = (*msg).clone();
|
||||
MessageSendEvent::BroadcastChannelUpdate {
|
||||
msg: crate::ln::msgs::ChannelUpdate { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::HandleError {ref node_id, ref action, } => {
|
||||
let mut node_id_nonref = (*node_id).clone();
|
||||
let mut action_nonref = (*action).clone();
|
||||
MessageSendEvent::HandleError {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
|
||||
action: crate::ln::msgs::ErrorAction::native_into(action_nonref),
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::PaymentFailureNetworkUpdate {ref update, } => {
|
||||
let mut update_nonref = (*update).clone();
|
||||
MessageSendEvent::PaymentFailureNetworkUpdate {
|
||||
update: crate::ln::msgs::HTLCFailChannelUpdate::native_into(update_nonref),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn native_into(native: nativeMessageSendEvent) -> Self {
|
||||
match native {
|
||||
nativeMessageSendEvent::SendAcceptChannel {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendAcceptChannel {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::AcceptChannel { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendOpenChannel {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendOpenChannel {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::OpenChannel { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendFundingCreated {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendFundingCreated {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::FundingCreated { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendFundingSigned {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendFundingSigned {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::FundingSigned { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendFundingLocked {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendFundingLocked {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::FundingLocked { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendAnnouncementSignatures {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendAnnouncementSignatures {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::AnnouncementSignatures { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::UpdateHTLCs {mut node_id, mut updates, } => {
|
||||
MessageSendEvent::UpdateHTLCs {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
updates: crate::ln::msgs::CommitmentUpdate { inner: Box::into_raw(Box::new(updates)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendRevokeAndACK {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendRevokeAndACK {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::RevokeAndACK { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendClosingSigned {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendClosingSigned {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::ClosingSigned { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendShutdown {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendShutdown {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::Shutdown { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::SendChannelReestablish {mut node_id, mut msg, } => {
|
||||
MessageSendEvent::SendChannelReestablish {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
msg: crate::ln::msgs::ChannelReestablish { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::BroadcastChannelAnnouncement {mut msg, mut update_msg, } => {
|
||||
MessageSendEvent::BroadcastChannelAnnouncement {
|
||||
msg: crate::ln::msgs::ChannelAnnouncement { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
update_msg: crate::ln::msgs::ChannelUpdate { inner: Box::into_raw(Box::new(update_msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::BroadcastNodeAnnouncement {mut msg, } => {
|
||||
MessageSendEvent::BroadcastNodeAnnouncement {
|
||||
msg: crate::ln::msgs::NodeAnnouncement { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::BroadcastChannelUpdate {mut msg, } => {
|
||||
MessageSendEvent::BroadcastChannelUpdate {
|
||||
msg: crate::ln::msgs::ChannelUpdate { inner: Box::into_raw(Box::new(msg)), is_owned: true },
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::HandleError {mut node_id, mut action, } => {
|
||||
MessageSendEvent::HandleError {
|
||||
node_id: crate::c_types::PublicKey::from_rust(&node_id),
|
||||
action: crate::ln::msgs::ErrorAction::native_into(action),
|
||||
}
|
||||
},
|
||||
nativeMessageSendEvent::PaymentFailureNetworkUpdate {mut update, } => {
|
||||
MessageSendEvent::PaymentFailureNetworkUpdate {
|
||||
update: crate::ln::msgs::HTLCFailChannelUpdate::native_into(update),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MessageSendEvent_free(this_ptr: MessageSendEvent) { }
|
||||
/// A trait indicating an object may generate message send events
|
||||
#[repr(C)]
|
||||
pub struct MessageSendEventsProvider {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Gets the list of pending events which were generated by previous actions, clearing the list
|
||||
/// in the process.
|
||||
#[must_use]
|
||||
pub get_and_clear_pending_msg_events: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_MessageSendEventZ,
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
|
||||
use lightning::util::events::MessageSendEventsProvider as rustMessageSendEventsProvider;
|
||||
impl rustMessageSendEventsProvider for MessageSendEventsProvider {
|
||||
fn get_and_clear_pending_msg_events(&self) -> Vec<lightning::util::events::MessageSendEvent> {
|
||||
let mut ret = (self.get_and_clear_pending_msg_events)(self.this_arg);
|
||||
let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { item.into_native() }); };
|
||||
local_ret
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for MessageSendEventsProvider {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn MessageSendEventsProvider_free(this_ptr: MessageSendEventsProvider) { }
|
||||
impl Drop for MessageSendEventsProvider {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// A trait indicating an object may generate events
|
||||
#[repr(C)]
|
||||
pub struct EventsProvider {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Gets the list of pending events which were generated by previous actions, clearing the list
|
||||
/// in the process.
|
||||
#[must_use]
|
||||
pub get_and_clear_pending_events: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_EventZ,
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
|
||||
use lightning::util::events::EventsProvider as rustEventsProvider;
|
||||
impl rustEventsProvider for EventsProvider {
|
||||
fn get_and_clear_pending_events(&self) -> Vec<lightning::util::events::Event> {
|
||||
let mut ret = (self.get_and_clear_pending_events)(self.this_arg);
|
||||
let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { item.into_native() }); };
|
||||
local_ret
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for EventsProvider {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn EventsProvider_free(this_ptr: EventsProvider) { }
|
||||
impl Drop for EventsProvider {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
121
lightning-c-bindings/src/util/logger.rs
Normal file
121
lightning-c-bindings/src/util/logger.rs
Normal file
|
@ -0,0 +1,121 @@
|
|||
//! Log traits live here, which are called throughout the library to provide useful information for
|
||||
//! debugging purposes.
|
||||
//!
|
||||
//! There is currently 2 ways to filter log messages. First one, by using compilation features, e.g \"max_level_off\".
|
||||
//! The second one, client-side by implementing check against Record Level field.
|
||||
//! Each module may have its own Logger or share one.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
/// An enum representing the available verbosity levels of the logger.
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub enum Level {
|
||||
///Designates logger being silent
|
||||
Off,
|
||||
/// Designates very serious errors
|
||||
Error,
|
||||
/// Designates hazardous situations
|
||||
Warn,
|
||||
/// Designates useful information
|
||||
Info,
|
||||
/// Designates lower priority information
|
||||
Debug,
|
||||
/// Designates very low priority, often extremely verbose, information
|
||||
Trace,
|
||||
}
|
||||
use lightning::util::logger::Level as nativeLevel;
|
||||
impl Level {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn to_native(&self) -> nativeLevel {
|
||||
match self {
|
||||
Level::Off => nativeLevel::Off,
|
||||
Level::Error => nativeLevel::Error,
|
||||
Level::Warn => nativeLevel::Warn,
|
||||
Level::Info => nativeLevel::Info,
|
||||
Level::Debug => nativeLevel::Debug,
|
||||
Level::Trace => nativeLevel::Trace,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn into_native(self) -> nativeLevel {
|
||||
match self {
|
||||
Level::Off => nativeLevel::Off,
|
||||
Level::Error => nativeLevel::Error,
|
||||
Level::Warn => nativeLevel::Warn,
|
||||
Level::Info => nativeLevel::Info,
|
||||
Level::Debug => nativeLevel::Debug,
|
||||
Level::Trace => nativeLevel::Trace,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn from_native(native: &nativeLevel) -> Self {
|
||||
match native {
|
||||
nativeLevel::Off => Level::Off,
|
||||
nativeLevel::Error => Level::Error,
|
||||
nativeLevel::Warn => Level::Warn,
|
||||
nativeLevel::Info => Level::Info,
|
||||
nativeLevel::Debug => Level::Debug,
|
||||
nativeLevel::Trace => Level::Trace,
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub(crate) fn native_into(native: nativeLevel) -> Self {
|
||||
match native {
|
||||
nativeLevel::Off => Level::Off,
|
||||
nativeLevel::Error => Level::Error,
|
||||
nativeLevel::Warn => Level::Warn,
|
||||
nativeLevel::Info => Level::Info,
|
||||
nativeLevel::Debug => Level::Debug,
|
||||
nativeLevel::Trace => Level::Trace,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Returns the most verbose logging level.
|
||||
#[must_use]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Level_max() -> crate::util::logger::Level {
|
||||
let mut ret = lightning::util::logger::Level::max();
|
||||
crate::util::logger::Level::native_into(ret)
|
||||
}
|
||||
|
||||
/// A trait encapsulating the operations required of a logger
|
||||
#[repr(C)]
|
||||
pub struct Logger {
|
||||
pub this_arg: *mut c_void,
|
||||
/// Logs the `Record`
|
||||
pub log: extern "C" fn (this_arg: *const c_void, record: *const std::os::raw::c_char),
|
||||
pub free: Option<extern "C" fn(this_arg: *mut c_void)>,
|
||||
}
|
||||
unsafe impl Sync for Logger {}
|
||||
unsafe impl Send for Logger {}
|
||||
|
||||
use lightning::util::logger::Logger as rustLogger;
|
||||
impl rustLogger for Logger {
|
||||
fn log(&self, record: &lightning::util::logger::Record) {
|
||||
let mut local_record = std::ffi::CString::new(format!("{}", record.args)).unwrap();
|
||||
(self.log)(self.this_arg, local_record.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
// We're essentially a pointer already, or at least a set of pointers, so allow us to be used
|
||||
// directly as a Deref trait in higher-level structs:
|
||||
impl std::ops::Deref for Logger {
|
||||
type Target = Self;
|
||||
fn deref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Calls the free function if one is set
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Logger_free(this_ptr: Logger) { }
|
||||
impl Drop for Logger {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.free {
|
||||
f(self.this_arg);
|
||||
}
|
||||
}
|
||||
}
|
11
lightning-c-bindings/src/util/mod.rs
Normal file
11
lightning-c-bindings/src/util/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
//! Some utility modules live here. See individual sub-modules for more info.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
||||
pub mod events;
|
||||
pub mod errors;
|
||||
pub mod ser;
|
||||
pub mod logger;
|
||||
pub mod config;
|
7
lightning-c-bindings/src/util/ser.rs
Normal file
7
lightning-c-bindings/src/util/ser.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
//! A very simple serialization framework which is used to serialize/deserialize messages as well
|
||||
//! as ChannelsManagers and ChannelMonitors.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use bitcoin::hashes::Hash;
|
||||
use crate::c_types::*;
|
||||
|
|
@ -226,6 +226,8 @@ impl ChainWatchedUtil {
|
|||
/// parameters with static lifetimes). Other times you can afford a reference, which is more
|
||||
/// efficient, in which case BlockNotifierRef is a more appropriate type. Defining these type
|
||||
/// aliases prevents issues such as overly long function definitions.
|
||||
///
|
||||
/// (C-not exported) as we let clients handle any reference counting they need to do
|
||||
pub type BlockNotifierArc<C> = Arc<BlockNotifier<'static, Arc<ChainListener>, C>>;
|
||||
|
||||
/// BlockNotifierRef is useful when you want a BlockNotifier that points to ChainListeners
|
||||
|
@ -273,6 +275,8 @@ impl<'a, CL: Deref + 'a, C: Deref> BlockNotifier<'a, CL, C>
|
|||
/// If the same listener is registered multiple times, unregistering
|
||||
/// will remove ALL occurrences of that listener. Comparison is done using
|
||||
/// the pointer returned by the Deref trait implementation.
|
||||
///
|
||||
/// (C-not exported) because the equality check would always fail
|
||||
pub fn unregister_listener(&self, listener: CL) {
|
||||
let mut vec = self.listeners.lock().unwrap();
|
||||
// item is a ref to an abstract thing that dereferences to a ChainListener,
|
||||
|
|
|
@ -35,6 +35,7 @@ impl OutPoint {
|
|||
}
|
||||
|
||||
/// Converts this OutPoint into the OutPoint field as used by rust-bitcoin
|
||||
/// (C-not exported) as the same type is used universally in the C bindings for all outpoints
|
||||
pub fn into_bitcoin_outpoint(self) -> BitcoinOutPoint {
|
||||
BitcoinOutPoint {
|
||||
txid: self.txid,
|
||||
|
|
|
@ -188,7 +188,7 @@ impl Readable for CounterpartyCommitmentSecrets {
|
|||
///
|
||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||
/// generated (ie our own).
|
||||
pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
|
||||
pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result<SecretKey, SecpError> {
|
||||
let mut sha = Sha256::engine();
|
||||
sha.input(&per_commitment_point.serialize());
|
||||
sha.input(&PublicKey::from_secret_key(&secp_ctx, &base_secret).serialize());
|
||||
|
@ -205,7 +205,7 @@ pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_co
|
|||
///
|
||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||
/// generated (ie our own).
|
||||
pub fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
|
||||
pub fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result<PublicKey, SecpError> {
|
||||
let mut sha = Sha256::engine();
|
||||
sha.input(&per_commitment_point.serialize());
|
||||
sha.input(&base_point.serialize());
|
||||
|
@ -219,7 +219,7 @@ pub fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_com
|
|||
///
|
||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||
/// generated (ie our own).
|
||||
pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
|
||||
pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result<SecretKey, SecpError> {
|
||||
let revocation_base_point = PublicKey::from_secret_key(&secp_ctx, &revocation_base_secret);
|
||||
let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
|
||||
|
||||
|
@ -252,7 +252,7 @@ pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1
|
|||
///
|
||||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
|
||||
/// generated (ie our own).
|
||||
pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
|
||||
pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result<PublicKey, SecpError> {
|
||||
let rev_append_commit_hash_key = {
|
||||
let mut sha = Sha256::engine();
|
||||
sha.input(&revocation_base_point.serialize());
|
||||
|
|
|
@ -180,12 +180,15 @@ pub(super) enum HTLCFailReason {
|
|||
}
|
||||
|
||||
/// payment_hash type, use to cross-lock hop
|
||||
/// (C-not exported) as we just use [u8; 32] directly
|
||||
#[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct PaymentHash(pub [u8;32]);
|
||||
/// payment_preimage type, use to route payment between hop
|
||||
/// (C-not exported) as we just use [u8; 32] directly
|
||||
#[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct PaymentPreimage(pub [u8;32]);
|
||||
/// payment_secret type, use to authenticate sender to the receiver and tie MPP HTLCs together
|
||||
/// (C-not exported) as we just use [u8; 32] directly
|
||||
#[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct PaymentSecret(pub [u8;32]);
|
||||
|
||||
|
@ -2919,6 +2922,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
|
|||
/// If successful, will generate a UpdateHTLCs event, so you should probably poll
|
||||
/// PeerManager::process_events afterwards.
|
||||
/// Note: This API is likely to change!
|
||||
/// (C-not exported) Cause its doc(hidden) anyway
|
||||
#[doc(hidden)]
|
||||
pub fn update_fee(&self, channel_id: [u8;32], feerate_per_kw: u32) -> Result<(), APIError> {
|
||||
let _ = self.total_consistency_lock.read().unwrap();
|
||||
|
@ -3738,7 +3742,6 @@ pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref, T:
|
|||
F::Target: FeeEstimator,
|
||||
L::Target: Logger,
|
||||
{
|
||||
|
||||
/// The keys provider which will give us relevant keys. Some keys will be loaded during
|
||||
/// deserialization.
|
||||
pub keys_manager: K,
|
||||
|
@ -3775,6 +3778,8 @@ pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref, T:
|
|||
///
|
||||
/// In such cases the latest local transactions will be sent to the tx_broadcaster included in
|
||||
/// this struct.
|
||||
///
|
||||
/// (C-not exported) because we have no HashMap bindings
|
||||
pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<ChanSigner>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -180,6 +180,8 @@ impl_writeable!(HTLCUpdate, 0, { payment_hash, payment_preimage, source });
|
|||
///
|
||||
/// If you're using this for local monitoring of your own channels, you probably want to use
|
||||
/// `OutPoint` as the key, which will give you a ManyChannelMonitor implementation.
|
||||
///
|
||||
/// (C-not exported) due to an unconstrained generic in `Key`
|
||||
pub struct SimpleManyChannelMonitor<Key, ChanSigner: ChannelKeys, T: Deref, F: Deref, L: Deref, C: Deref>
|
||||
where T::Target: BroadcasterInterface,
|
||||
F::Target: FeeEstimator,
|
||||
|
@ -1421,6 +1423,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
|
|||
|
||||
/// Gets a list of txids, with their output scripts (in the order they appear in the
|
||||
/// transaction), which we must learn about spends of via block_connected().
|
||||
///
|
||||
/// (C-not exported) because we have no HashMap bindings
|
||||
pub fn get_outputs_to_watch(&self) -> &HashMap<Txid, Vec<Script>> {
|
||||
&self.outputs_to_watch
|
||||
}
|
||||
|
@ -1429,6 +1433,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
|
|||
/// Generally useful when deserializing as during normal operation the return values of
|
||||
/// block_connected are sufficient to ensure all relevant outpoints are being monitored (note
|
||||
/// that the get_funding_txo outpoint and transaction must also be monitored for!).
|
||||
///
|
||||
/// (C-not exported) as there is no practical way to track lifetimes of returned values.
|
||||
pub fn get_monitored_outpoints(&self) -> Vec<(Txid, u32, &Script)> {
|
||||
let mut res = Vec::with_capacity(self.remote_commitment_txn_on_chain.len() * 2);
|
||||
for (ref txid, &(_, ref outputs)) in self.remote_commitment_txn_on_chain.iter() {
|
||||
|
|
|
@ -279,6 +279,8 @@ mod sealed {
|
|||
|
||||
/// Tracks the set of features which a node implements, templated by the context in which it
|
||||
/// appears.
|
||||
///
|
||||
/// (C-not exported) as we map the concrete feature types below directly instead
|
||||
pub struct Features<T: sealed::Context> {
|
||||
/// Note that, for convenience, flags is LITTLE endian (despite being big-endian on the wire)
|
||||
flags: Vec<u8>,
|
||||
|
|
|
@ -646,6 +646,7 @@ pub enum HTLCFailChannelUpdate {
|
|||
/// As we wish to serialize these differently from Option<T>s (Options get a tag byte, but
|
||||
/// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a
|
||||
/// separate enum type for them.
|
||||
/// (C-not exported) due to a free generic in T
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum OptionalField<T> {
|
||||
/// Optional field is included in message
|
||||
|
|
|
@ -260,7 +260,7 @@ pub struct DirectionalChannelInfo {
|
|||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
pub last_update_message: Option<msgs::ChannelUpdate>,
|
||||
pub last_update_message: Option<ChannelUpdate>,
|
||||
}
|
||||
|
||||
impl fmt::Display for DirectionalChannelInfo {
|
||||
|
@ -300,7 +300,7 @@ pub struct ChannelInfo {
|
|||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
pub announcement_message: Option<msgs::ChannelAnnouncement>,
|
||||
pub announcement_message: Option<ChannelAnnouncement>,
|
||||
}
|
||||
|
||||
impl fmt::Display for ChannelInfo {
|
||||
|
@ -371,7 +371,7 @@ pub struct NodeAnnouncementInfo {
|
|||
/// Mostly redundant with the data we store in fields explicitly.
|
||||
/// Everything else is useful only for sending out for initial routing sync.
|
||||
/// Not stored if contains excess data to prevent DoS.
|
||||
pub announcement_message: Option<msgs::NodeAnnouncement>
|
||||
pub announcement_message: Option<NodeAnnouncement>
|
||||
}
|
||||
|
||||
impl Writeable for NodeAnnouncementInfo {
|
||||
|
@ -526,13 +526,19 @@ impl fmt::Display for NetworkGraph {
|
|||
|
||||
impl NetworkGraph {
|
||||
/// Returns all known valid channels' short ids along with announced channel info.
|
||||
///
|
||||
/// (C-not exported) because we have no mapping for `BTreeMap`s
|
||||
pub fn get_channels<'a>(&'a self) -> &'a BTreeMap<u64, ChannelInfo> { &self.channels }
|
||||
/// Returns all known nodes' public keys along with announced node info.
|
||||
///
|
||||
/// (C-not exported) because we have no mapping for `BTreeMap`s
|
||||
pub fn get_nodes<'a>(&'a self) -> &'a BTreeMap<PublicKey, NodeInfo> { &self.nodes }
|
||||
|
||||
/// Get network addresses by node id.
|
||||
/// Returns None if the requested node is completely unknown,
|
||||
/// or if node announcement for the node was never received.
|
||||
///
|
||||
/// (C-not exported) as there is no practical way to track lifetimes of returned values.
|
||||
pub fn get_addresses<'a>(&'a self, pubkey: &PublicKey) -> Option<&'a Vec<NetAddress>> {
|
||||
if let Some(node) = self.nodes.get(pubkey) {
|
||||
if let Some(node_info) = node.announcement_info.as_ref() {
|
||||
|
|
|
@ -86,6 +86,7 @@ impl Level {
|
|||
|
||||
/// A Record, unit of logging output with Metadata to enable filtering
|
||||
/// Module_path, file, line to inform on log's source
|
||||
/// (C-not exported) - we convert to a const char* instead
|
||||
#[derive(Clone,Debug)]
|
||||
pub struct Record<'a> {
|
||||
/// The verbosity level of the message.
|
||||
|
@ -102,6 +103,7 @@ pub struct Record<'a> {
|
|||
|
||||
impl<'a> Record<'a> {
|
||||
/// Returns a new Record.
|
||||
/// (C-not exported) as fmt can't be used in C
|
||||
#[inline]
|
||||
pub fn new(level: Level, args: fmt::Arguments<'a>, module_path: &'a str, file: &'a str, line: u32) -> Record<'a> {
|
||||
Record {
|
||||
|
|
|
@ -37,6 +37,8 @@ const MAX_BUF_SIZE: usize = 64 * 1024;
|
|||
/// buffers being written into.
|
||||
/// An impl is provided for any type that also impls std::io::Write which simply ignores size
|
||||
/// hints.
|
||||
///
|
||||
/// (C-not exported) as we only export serialization to/from byte arrays instead
|
||||
pub trait Writer {
|
||||
/// Writes the given buf out. See std::io::Write::write_all for more
|
||||
fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error>;
|
||||
|
@ -159,6 +161,8 @@ impl<R: Read> Read for ReadTrackingReader<R> {
|
|||
}
|
||||
|
||||
/// A trait that various rust-lightning types implement allowing them to be written out to a Writer
|
||||
///
|
||||
/// (C-not exported) as we only export serialization to/from byte arrays instead
|
||||
pub trait Writeable {
|
||||
/// Writes self out to the given Writer
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error>;
|
||||
|
@ -186,6 +190,8 @@ impl<'a, T: Writeable> Writeable for &'a T {
|
|||
}
|
||||
|
||||
/// A trait that various rust-lightning types implement allowing them to be read in from a Read
|
||||
///
|
||||
/// (C-not exported) as we only export serialization to/from byte arrays instead
|
||||
pub trait Readable
|
||||
where Self: Sized
|
||||
{
|
||||
|
@ -195,6 +201,8 @@ pub trait Readable
|
|||
|
||||
/// A trait that various higher-level rust-lightning types implement allowing them to be read in
|
||||
/// from a Read given some additional set of arguments which is required to deserialize.
|
||||
///
|
||||
/// (C-not exported) as we only export serialization to/from byte arrays instead
|
||||
pub trait ReadableArgs<P>
|
||||
where Self: Sized
|
||||
{
|
||||
|
@ -203,6 +211,8 @@ pub trait ReadableArgs<P>
|
|||
}
|
||||
|
||||
/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a Read
|
||||
///
|
||||
/// (C-not exported) as we only export serialization to/from byte arrays instead
|
||||
pub trait MaybeReadable
|
||||
where Self: Sized
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue