Merge pull request #34 from TheBlueMatt/main v0.0.99.0
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Fri, 9 Jul 2021 18:48:20 +0000 (18:48 +0000)
committerGitHub <noreply@github.com>
Fri, 9 Jul 2021 18:48:20 +0000 (18:48 +0000)
Add a POSIX C LDK networking library

20 files changed:
c-bindings-gen/src/main.rs
genbindings.sh
ldk-net/ldk_net.c [new file with mode: 0644]
ldk-net/ldk_net.h [new file with mode: 0644]
lightning-c-bindings/Cargo.toml
lightning-c-bindings/demo.cpp
lightning-c-bindings/include/ldk_rust_types.h
lightning-c-bindings/include/lightning.h
lightning-c-bindings/include/lightningpp.hpp
lightning-c-bindings/src/c_types/derived.rs
lightning-c-bindings/src/lightning/chain/channelmonitor.rs
lightning-c-bindings/src/lightning/chain/mod.rs
lightning-c-bindings/src/lightning/ln/channelmanager.rs
lightning-c-bindings/src/lightning/ln/msgs.rs
lightning-c-bindings/src/lightning/ln/peer_handler.rs
lightning-c-bindings/src/lightning/util/config.rs
lightning-c-bindings/src/lightning/util/events.rs
lightning-c-bindings/src/lightning/util/logger.rs
lightning-c-bindings/src/lightning/util/message_signing.rs
lightning-c-bindings/src/lightning_invoice/mod.rs

index 8bbbdf03765579e5636c49aa3dfd9e937cee8768..9693e3d560a04575cf51863ec180ce1d37956434 100644 (file)
@@ -280,10 +280,9 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                writeln!(w, "\tpub set_{}: Option<extern \"C\" fn(&{})>,", m.sig.ident, trait_name).unwrap();
                                                generated_fields.push((format!("set_{}", m.sig.ident), true));
                                                // Note that cbindgen will now generate
-                                               // typedef struct Thing {..., set_thing: (const Thing*), ...} Thing;
+                                               // typedef struct Thing {..., set_thing: (const struct Thing*), ...} Thing;
                                                // which does not compile since Thing is not defined before it is used.
                                                writeln!(extra_headers, "struct LDK{};", trait_name).unwrap();
-                                               writeln!(extra_headers, "typedef struct LDK{} LDK{};", trait_name, trait_name).unwrap();
                                                continue;
                                        }
                                        // Sadly, this currently doesn't do what we want, but it should be easy to get
@@ -317,7 +316,6 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                ("std::cmp::Eq", _)|("core::cmp::Eq", _) => {
                        writeln!(w, "\t/// Checks if two objects are equal given this object's this_arg pointer and another object.").unwrap();
                        writeln!(w, "\tpub eq: extern \"C\" fn (this_arg: *const c_void, other_arg: &{}) -> bool,", trait_name).unwrap();
-                       writeln!(extra_headers, "typedef struct LDK{} LDK{};", trait_name, trait_name).unwrap();
                        generated_fields.push(("eq".to_owned(), true));
                },
                ("std::hash::Hash", _)|("core::hash::Hash", _) => {
index fd1b7851981f332b2173f73a0dfe8a92421ded55..094bfedc3a8d9e8af8430fce1fef418f892c6666 100755 (executable)
@@ -209,15 +209,23 @@ fi
 gcc $LOCAL_CFLAGS -Wall -g -pthread demo.c target/debug/libldk.a -ldl
 ./a.out
 
-# And run the C++ demo app in valgrind to test memory model correctness and lack of leaks.
+# And run the C++ demo app
 g++ $LOCAL_CFLAGS -std=c++11 -Wall -g -pthread demo.cpp -Ltarget/debug/ -lldk -ldl
+LD_LIBRARY_PATH=target/debug/ ./a.out > /dev/null
+
+# Finally, run the C++ demo app with our native networking library
+# in valgrind to test memory model correctness and lack of leaks.
+gcc $LOCAL_CFLAGS -std=c99 -Wall -g -pthread -I../ldk-net ../ldk-net/ldk_net.c -c -o ldk_net.o
+g++ $LOCAL_CFLAGS -std=c++11 -Wall -g -pthread -DREAL_NET -I../ldk-net ldk_net.o demo.cpp target/debug/libldk.a -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
+       valgrind --error-exitcode=4 --memcheck:leak-check=full --show-leak-kinds=all ./a.out
        echo
 else
        echo "WARNING: Please install valgrind for more testing"
+       ./a.out
 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++ $LOCAL_CFLAGS -std=c++11 demo.cpp target/debug/libldk.a -ldl
@@ -248,6 +256,11 @@ if [ "$HOST_PLATFORM" = "host: x86_64-unknown-linux-gnu" ]; then
                        clang++-$LLVM_V $LOCAL_CFLAGS -std=c++11 -fsanitize=memory -fsanitize-memory-track-origins -g demo.cpp target/debug/libldk.a -ldl
                        ./a.out >/dev/null
 
+                       # ...then the C++ demo app with the ldk_net network implementation
+                       clang-$LLVM_V $LOCAL_CFLAGS -std=c99 -fsanitize=memory -fsanitize-memory-track-origins -g -I../ldk-net ../ldk-net/ldk_net.c -c -o ldk_net.o
+                       clang++-$LLVM_V $LOCAL_CFLAGS -std=c++11 -fsanitize=memory -fsanitize-memory-track-origins -g -DREAL_NET -I../ldk-net ldk_net.o demo.cpp target/debug/libldk.a -ldl
+                       ./a.out >/dev/null
+
                        # restore exit-on-failure
                        set -e
                else
@@ -260,7 +273,7 @@ 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 '.')
+RUSTC_LLVM_V=$(rustc --version --verbose | grep "LLVM version" | awk '{ print substr($3, 0, 4); }')
 
 if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then
        # Apple is special, as always, and their versions of clang aren't
@@ -269,16 +282,26 @@ if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then
                echo "Apple clang isn't compatible with upstream clang, install upstream clang"
                CLANG_LLVM_V="0"
        else
-               CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 2); }' | tr -d '.')
+               CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 4); }')
+               if [ -x "$(which ld64.lld)" ]; then
+                       LLD_LLVM_V="$(ld64.lld --version | awk '{ print substr($2, 0, 4); }')"
+               fi
        fi
 else
-       CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 2); }' | tr -d '.')
+       CLANG_LLVM_V=$(clang --version | head -n1 | awk '{ print substr($4, 0, 4); }')
+       if [ -x "$(which ld.lld)" ]; then
+               LLD_LLVM_V="$(ld.lld --version | awk '{ print substr($2, 0, 4); }')"
+       fi
 fi
 
+
 if [ "$CLANG_LLVM_V" = "$RUSTC_LLVM_V" ]; then
        CLANG=clang
        CLANGPP=clang++
-elif [ "$(which clang-$RUSTC_LLVM_V)" != "" ]; then
+       if [ "$LLD_LLVM_V" = "$CLANG_LLVM_V" ]; then
+               LLD=lld
+       fi
+elif [ -x "$(which clang-$RUSTC_LLVM_V)" ]; then
        CLANG="$(which clang-$RUSTC_LLVM_V)"
        CLANGPP="$(which clang++-$RUSTC_LLVM_V || echo clang++)"
        if [ "$($CLANG --version)" != "$($CLANGPP --version)" ]; then
@@ -286,6 +309,14 @@ elif [ "$(which clang-$RUSTC_LLVM_V)" != "" ]; then
                unset CLANG
                unset CLANGPP
        fi
+       if [ "$LLD_LLVM_V" != "$RUSTC_LLVM_V" ]; then
+               LLD="$(which lld-$RUSTC_LLVM_V || echo lld)"
+               LLD_LLVM_V="$(ld.$LLD --version | awk '{ print substr($2, 0, 4); }')"
+               if [ "$LLD_LLVM_V" != "$RUSTC_LLVM_V" ]; then
+                       echo "Could not find a workable version of lld, not using cross-language LTO"
+                       unset LLD
+               fi
+       fi
 fi
 
 if [ "$CLANG" != "" -a "$CLANGPP" = "" ]; then
@@ -315,6 +346,11 @@ if [ "$HOST_PLATFORM" = "host: x86_64-unknown-linux-gnu" -o "$HOST_PLATFORM" = "
                # ...then the C++ demo app
                $CLANGPP $LOCAL_CFLAGS -std=c++11 -fsanitize=address -g demo.cpp target/debug/libldk.a -ldl
                ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' ./a.out >/dev/null
+
+               # ...then the C++ demo app with the ldk_net network implementation
+               $CLANG $LOCAL_CFLAGS -fsanitize=address -g -I../ldk-net ../ldk-net/ldk_net.c -c -o ldk_net.o
+               $CLANGPP $LOCAL_CFLAGS -std=c++11 -fsanitize=address -g -DREAL_NET -I../ldk-net ldk_net.o demo.cpp target/debug/libldk.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
@@ -326,7 +362,7 @@ fi
 # Clear stale release build artifacts from previous runs
 cargo clean --release
 CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C lto
-clang++ $LOCAL_CFLAGS -std=c++11 -flto -O2 demo.cpp target/release/libldk.a -ldl
+clang++ $LOCAL_CFLAGS -std=c++11 -O2 demo.cpp target/release/libldk.a -ldl
 
 strip ./a.out
 echo "C++ Bin size and runtime with only RL (LTO) optimized:"
@@ -362,7 +398,7 @@ if [ "$CFLAGS_aarch64_apple_darwin" != "" ]; then
        RUSTFLAGS="$BASE_RUSTFLAGS -C target-cpu=apple-a14" CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release --target aarch64-apple-darwin -- -C lto
 fi
 
-if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then
+if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" -a "$LLD" != "" ]; 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
@@ -371,7 +407,7 @@ if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then
        export CFLAGS_$ENV_TARGET="$BASE_CFLAGS -O3 -fPIC -fembed-bitcode -march=sandybridge"
        # Rust doesn't recognize CFLAGS changes, so we need to clean build artifacts
        cargo clean --release
-       CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C linker-plugin-lto -C lto -C link-arg=-fuse-ld=lld
+       CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C linker-plugin-lto -C lto -C linker=$CLANG -C link-arg=-fuse-ld=$LLD
        $CLANGPP $LOCAL_CFLAGS -flto -fuse-ld=lld -O2 demo.cpp target/release/libldk.a -ldl
        strip ./a.out
        echo "C++ Bin size and runtime with cross-language LTO:"
diff --git a/ldk-net/ldk_net.c b/ldk-net/ldk_net.c
new file mode 100644 (file)
index 0000000..fb349ae
--- /dev/null
@@ -0,0 +1,410 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+/**
+ * This file implements what you need to get networking up with LDK using
+ * standard POSIX APIs. Its not particularly effecient (in fact quite the
+ * opposite) but should be more than sufficient for most use-cases.
+ */
+
+#include "ldk_net.h"
+
+#include <lightning.h>
+
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <pthread.h>
+#include <poll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#define IS_BSD
+#endif
+
+#define MAX_CONNS 1024
+struct SocketHandler {
+       const struct LDKPeerManager *ldk_peer_manager;
+       pthread_t socket_thread;
+       bool should_exit;
+       int pipefds[2];
+       // pollfds ands sockcount may only be written to with a lock on
+       // sockets_mutex.
+       // sockcount mut always be the number of sockets in pollfds
+       // Items in pollfds may only be removed in the socket_thread, other threads
+       // may only append new file descriptors at the end (via register_socket).
+       pthread_mutex_t sockets_mutex;
+       struct pollfd pollfds[MAX_CONNS];
+       nfds_t sockcount;
+};
+
+int register_socket(struct SocketHandler* handler, int fd, int is_listen_sock) {
+       int fd_flags = fcntl(fd, F_GETFL, 0);
+       if (fd_flags < 0) return -1;
+       if (fcntl(fd, F_SETFL, fd_flags | O_NONBLOCK) == -1) return -1;
+
+       if (!is_listen_sock) {
+               int opt = 1;
+               if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&opt, sizeof(opt))) return -1;
+#ifdef IS_BSD
+               if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt))) return -1;
+#endif
+       }
+
+       int lockres = pthread_mutex_lock(&handler->sockets_mutex);
+       assert(lockres == 0);
+
+       handler->pollfds[handler->sockcount].fd = fd;
+       handler->pollfds[handler->sockcount].events = POLLIN;
+       handler->pollfds[handler->sockcount].revents = 0;
+       handler->sockcount++;
+       assert(handler->sockcount <= MAX_CONNS);
+
+       lockres = pthread_mutex_unlock(&handler->sockets_mutex);
+       assert(lockres == 0);
+
+       uint8_t dummy = 0;
+       write(handler->pipefds[1], &dummy, 1);
+
+       return 0;
+}
+
+struct Descriptor {
+       struct SocketHandler *handler;
+       int fd;
+};
+
+static uintptr_t sock_send_data(void* desc, struct LDKu8slice data, bool resume_read) {
+       struct Descriptor *descriptor = (struct Descriptor*)desc;
+       ssize_t write_count = send(descriptor->fd, data.data, data.datalen, MSG_NOSIGNAL);
+       bool pause_read = false;
+       if (write_count <= 0) {
+               if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                       pause_read = true;
+                       write_count = 0;
+               } else {
+                       shutdown(descriptor->fd, SHUT_RDWR);
+                       uint8_t dummy = 0;
+                       write(descriptor->handler->pipefds[1], &dummy, 1);
+                       return 0;
+               }
+       } else if (write_count < data.datalen) {
+               pause_read = true;
+       }
+       if (pause_read || resume_read) {
+               int lockres = pthread_mutex_lock(&descriptor->handler->sockets_mutex);
+               assert(lockres == 0);
+               for (int i = 0; i < descriptor->handler->sockcount; i++) {
+                       if (descriptor->handler->pollfds[i].fd == descriptor->fd) {
+                               if (pause_read) {
+                                       descriptor->handler->pollfds[i].events &= POLLIN;
+                                       descriptor->handler->pollfds[i].events |= POLLOUT;
+                               } else {
+                                       descriptor->handler->pollfds[i].events |= POLLIN;
+                               }
+                               break;
+                       }
+               }
+               lockres = pthread_mutex_unlock(&descriptor->handler->sockets_mutex);
+               assert(lockres == 0);
+               uint8_t dummy = 0;
+               write(descriptor->handler->pipefds[1], &dummy, 1);
+       }
+
+       return write_count;
+}
+static void sock_disconnect(void* desc) {
+       struct Descriptor *descriptor = (struct Descriptor*)desc;
+       shutdown(descriptor->fd, SHUT_RDWR);
+       uint8_t dummy = 0;
+       write(descriptor->handler->pipefds[1], &dummy, 1);
+}
+static bool sock_eq(const void* desc, const struct LDKSocketDescriptor *other_arg) {
+       const struct Descriptor *descriptor = (const struct Descriptor*)desc;
+       const struct Descriptor *other_descriptor = (const struct Descriptor*)other_arg->this_arg;
+       return descriptor->fd == other_descriptor->fd;
+}
+static uint64_t sock_hash(const void* desc) {
+       const struct Descriptor *descriptor = (const struct Descriptor*)desc;
+       return (uint64_t)descriptor->fd;
+}
+static void* sock_clone(const void* desc) {
+       const struct Descriptor *descriptor = (const struct Descriptor*)desc;
+       struct Descriptor *new_desc = malloc(sizeof(struct Descriptor));
+       new_desc->handler = descriptor->handler;
+       new_desc->fd = descriptor->fd;
+       return new_desc;
+}
+static void sock_free(void* desc) {
+       free(desc);
+}
+
+static inline LDKSocketDescriptor get_descriptor(struct SocketHandler *handler, int fd) {
+       struct Descriptor *desc = malloc(sizeof(struct Descriptor));
+       desc->handler = handler;
+       desc->fd = fd;
+       LDKSocketDescriptor ret = {
+               .this_arg = (void*)desc,
+               .send_data = sock_send_data,
+               .disconnect_socket = sock_disconnect,
+               .eq = sock_eq,
+               .hash = sock_hash,
+               .clone = sock_clone,
+               .free = sock_free,
+       };
+       return ret;
+}
+
+static void *sock_thread_fn(void* arg) {
+       struct SocketHandler *handler = (struct SocketHandler*) arg;
+
+       int lockres;
+       struct pollfd pollfds[MAX_CONNS + 1];
+       int fd_count;
+
+       int close_socks[MAX_CONNS];
+       int close_socks_count = 0;
+
+       uint8_t readbuf[8192];
+
+       while (!handler->should_exit) {
+               {
+                       lockres = pthread_mutex_lock(&handler->sockets_mutex);
+                       assert(lockres == 0);
+                       memcpy(pollfds, handler->pollfds, sizeof(struct pollfd) * handler->sockcount);
+                       fd_count = handler->sockcount;
+                       lockres = pthread_mutex_unlock(&handler->sockets_mutex);
+                       assert(lockres == 0);
+               }
+               pollfds[fd_count].fd = handler->pipefds[0];
+               pollfds[fd_count].events = POLLIN;
+               fd_count++;
+
+               int pollres = poll(pollfds, fd_count, 10000);
+               assert(pollres != -1);
+               close_socks_count = 0;
+
+               read(pollfds[fd_count-1].fd, readbuf, sizeof(readbuf)); // Empty out the pipe
+
+               if (pollres > 0) {
+                       for (int i = 0; i < fd_count - 1; i++) {
+                               if (pollfds[i].revents) {
+                                       LDKSocketDescriptor descriptor = get_descriptor(handler, pollfds[i].fd);
+                                       if (pollfds[i].revents & POLLIN) {
+                                               int readlen = read(pollfds[i].fd, readbuf, sizeof(readbuf));
+                                               if (readlen < 0) {
+                                                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                                                               // Spurious wake.
+                                                       } else if (errno == EINVAL || errno == ENOTCONN) {
+                                                               // Assume we're a listening socket!
+                                                               int newfd = accept(pollfds[i].fd, NULL, NULL);
+                                                               if (newfd >= 0) {
+                                                                       // Received a new connection, register it!
+                                                                       LDKSocketDescriptor new_descriptor = get_descriptor(handler, newfd);
+                                                                       LDKCResult_NonePeerHandleErrorZ con_res = PeerManager_new_inbound_connection(handler->ldk_peer_manager, new_descriptor);
+                                                                       if (con_res.result_ok) {
+                                                                               if (register_socket(handler, newfd, 0))
+                                                                                       shutdown(newfd, SHUT_RDWR);
+                                                                       } else
+                                                                               close(newfd);
+                                                                       CResult_NonePeerHandleErrorZ_free(con_res);
+                                                               } else {
+                                                                       // Maybe it wasn't a listening socket, disconnect!
+                                                                       close_socks[close_socks_count++] = i;
+                                                               }
+                                                       } else {
+                                                               close_socks[close_socks_count++] = i;
+                                                       }
+                                               } else if (readlen == 0) {
+                                                       // EOF
+                                                       close_socks[close_socks_count++] = i;
+                                               } else {
+                                                       LDKu8slice data = {
+                                                               .data = readbuf,
+                                                               .datalen = readlen,
+                                                       };
+                                                       LDKCResult_boolPeerHandleErrorZ res = PeerManager_read_event(handler->ldk_peer_manager, &descriptor, data);
+                                                       if (res.result_ok) {
+                                                               if (*res.contents.result) {
+                                                                       lockres = pthread_mutex_lock(&handler->sockets_mutex);
+                                                                       assert(lockres == 0);
+                                                                       assert(handler->pollfds[i - 1].fd == pollfds[i].fd); // Only we change fd order!
+                                                                       handler->pollfds[i - 1].events &= POLLIN;
+                                                                       handler->pollfds[i - 1].events |= POLLOUT;
+                                                                       lockres = pthread_mutex_unlock(&handler->sockets_mutex);
+                                                                       assert(lockres == 0);
+                                                               }
+                                                       } else {
+                                                               close_socks[close_socks_count++] = i;
+                                                       }
+                                                       CResult_boolPeerHandleErrorZ_free(res);
+                                               }
+                                       }
+                                       if (pollfds[i].revents & POLLOUT) {
+                                               LDKCResult_NonePeerHandleErrorZ res = PeerManager_write_buffer_space_avail(handler->ldk_peer_manager, &descriptor);
+                                               if (!res.result_ok) {
+                                                       close_socks[close_socks_count++] = i;
+                                               }
+                                               CResult_NonePeerHandleErrorZ_free(res);
+                                       }
+                                       SocketDescriptor_free(descriptor);
+                               }
+                       }
+               }
+
+               // We only do the actual socket disconnect handling in this thread,
+               // other threads may append to pollfds and call shutdown().
+               // Thus, in this thread, we first call socket_disconnected for each
+               // socket we're gonna remove, then we walk the sockets and close() each
+               // which should be disconnecting, shifting the remaining sockets down
+               // as we walk.
+               for (int i = 0; i < close_socks_count; i++) {
+                       LDKSocketDescriptor descriptor = get_descriptor(handler, handler->pollfds[close_socks[i]].fd);
+                       PeerManager_socket_disconnected(handler->ldk_peer_manager, &descriptor);
+                       SocketDescriptor_free(descriptor);
+               }
+
+               lockres = pthread_mutex_lock(&handler->sockets_mutex);
+               assert(lockres == 0);
+               int close_idx = 0;
+               for (int i = 0; close_socks_count != 0 && i < handler->sockcount; i++) {
+                       if (close_idx < close_socks_count && close_socks[close_idx] == i) {
+                               close(handler->pollfds[i].fd);
+                               close_idx++;
+                       } else {
+                               handler->pollfds[i-close_idx] = handler->pollfds[i];
+                       }
+               }
+               assert(close_idx == close_socks_count);
+               handler->sockcount -= close_socks_count;
+               lockres = pthread_mutex_unlock(&handler->sockets_mutex);
+               assert(lockres == 0);
+
+               PeerManager_process_events(handler->ldk_peer_manager);
+       }
+
+       lockres = pthread_mutex_lock(&handler->sockets_mutex);
+       assert(lockres == 0);
+       for (int i = 0; i < handler->sockcount; i++) {
+               LDKSocketDescriptor descriptor = get_descriptor(handler, handler->pollfds[i].fd);
+               PeerManager_socket_disconnected(handler->ldk_peer_manager, &descriptor);
+               SocketDescriptor_free(descriptor);
+       }
+
+       for (int i = 0; i < handler->sockcount; i++) {
+               close(handler->pollfds[i].fd);
+       }
+       close(handler->pipefds[0]);
+       close(handler->pipefds[1]);
+       handler->sockcount = 0;
+       lockres = pthread_mutex_unlock(&handler->sockets_mutex);
+       assert(lockres == 0);
+
+       return NULL;
+}
+
+
+void* init_socket_handling(const struct LDKPeerManager *NONNULL_PTR ldk_peer_manager) {
+       struct SocketHandler *handler = NULL;
+
+       handler = (struct SocketHandler*) calloc(1, sizeof(struct SocketHandler));
+       if (!handler) goto err;
+       handler->pipefds[0] = -1;
+       handler->pipefds[1] = -1;
+
+       handler->ldk_peer_manager = ldk_peer_manager;
+       handler->should_exit = false;
+
+       if (pipe(handler->pipefds) != 0) goto err;
+
+       int fd_flags = fcntl(handler->pipefds[0], F_GETFL, 0);
+       if (fd_flags < 0) goto err;
+       if (fcntl(handler->pipefds[0], F_SETFL, fd_flags | O_NONBLOCK) == -1) goto err;
+
+       if (pthread_mutex_init(&handler->sockets_mutex, NULL) != 0) goto err;
+       if (pthread_create(&handler->socket_thread, NULL, sock_thread_fn, handler) != 0) {
+               pthread_mutex_destroy(&handler->sockets_mutex);
+               goto err;
+       }
+
+       return handler;
+
+err:
+       if (handler) {
+               if (handler->pipefds[0] != -1) close(handler->pipefds[0]);
+               if (handler->pipefds[1] != -1) close(handler->pipefds[1]);
+               free(handler);
+       }
+       return NULL;
+}
+
+void interrupt_socket_handling(void* arg) {
+       struct SocketHandler *handler = (struct SocketHandler*) arg;
+       handler->should_exit = true;
+       uint8_t dummy = 0;
+       write(handler->pipefds[1], &dummy, 1);
+       void *retval;
+       int ret = pthread_join(handler->socket_thread, &retval);
+       assert(ret == 0);
+       free(handler);
+}
+
+int socket_connect(void* arg, LDKPublicKey pubkey, struct sockaddr *addr, size_t addrlen) {
+       struct SocketHandler *handler = (struct SocketHandler*) arg;
+
+       int fd = socket(addr->sa_family, SOCK_STREAM, 0);
+       if (fd < 0) return -1;
+
+       struct timeval timeout;
+       timeout.tv_sec = 1;
+       timeout.tv_usec = 0;
+       if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout))) return -2;
+       if (connect(fd, addr, addrlen)) return -3;
+       timeout.tv_sec = 120;
+       if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout))) return -3;
+
+       if (register_socket(handler, fd, 0)) return -4;
+
+       LDKSocketDescriptor descriptor = get_descriptor(handler, fd);
+       LDKCResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(handler->ldk_peer_manager, pubkey, descriptor);
+       if (con_res.result_ok) {
+               ssize_t write_count = send(fd, con_res.contents.result->data, con_res.contents.result->datalen, MSG_NOSIGNAL);
+               if (write_count != con_res.contents.result->datalen)
+                       shutdown(fd, SHUT_RDWR);
+       } else {
+               shutdown(fd, SHUT_RDWR);
+       }
+       CResult_CVec_u8ZPeerHandleErrorZ_free(con_res);
+
+       return 0;
+}
+
+int socket_bind(void* arg, struct sockaddr *addr, socklen_t addrlen) {
+       struct SocketHandler *handler = (struct SocketHandler*) arg;
+       int fd = socket(addr->sa_family, SOCK_STREAM, 0);
+       if (fd < 0) return -1;
+
+       int reuseon = 1;
+       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseon, sizeof(reuseon))) return -2;
+
+       if (bind(fd, addr, addrlen)) return -3;
+       if (listen(fd, 32)) return -4;
+
+       if (register_socket(handler, fd, 1)) return -5;
+
+       return 0;
+}
diff --git a/ldk-net/ldk_net.h b/ldk-net/ldk_net.h
new file mode 100644 (file)
index 0000000..258b5ba
--- /dev/null
@@ -0,0 +1,27 @@
+#include <lightning.h>
+#include <sys/socket.h>
+/**
+ * Initializes socket handling and spawns a background thread to handle socket
+ * events and pass them to the given LDKPeerManager.
+ *
+ * Returns NULL on error, otherwise an opaque pointer which should be passed as
+ * `handler` in the remaining functions.
+ */
+void* init_socket_handling(const struct LDKPeerManager *NONNULL_PTR ldk_peer_manger);
+/**
+ * Stop the socket handling thread and free socket handling resources for the
+ * given handler, as returned by init_socket_handling.
+ */
+void interrupt_socket_handling(void* handler);
+/**
+ * Bind the given address to accept incoming connections on the given handler's
+ * background thread.
+ * Returns 0 on success.
+ */
+int socket_bind(void* handler, struct sockaddr *addr, socklen_t addrlen);
+/**
+ * Connect to the given address and handle socket events on the given handler's
+ * background thread.
+ * Returns 0 on success.
+ */
+int socket_connect(void* handler, LDKPublicKey counterparty_pubkey, struct sockaddr *addr, size_t addrlen);
index 93e4d86e57eef64f6cbe182123eeb2736560105f..ab108810a182ebfcdc1be85f766ce5f1e1df011c 100644 (file)
@@ -16,16 +16,12 @@ crate-type = ["staticlib"
 
 [dependencies]
 bitcoin = "0.26"
-secp256k1 = { version = "0.20.1", features = ["global-context-less-secure"] }
+secp256k1 = { version = "0.20.3", features = ["global-context-less-secure"] }
 # Note that the following line is matched by genbindings to update the path
-lightning = { git = "https://github.com/rust-bitcoin/rust-lightning", rev = "294009969aef617df4184ff41ef6daa5a445f213", features = ["allow_wallclock_use"] }
-lightning-persister = { git = "https://github.com/rust-bitcoin/rust-lightning", rev = "294009969aef617df4184ff41ef6daa5a445f213" }
-lightning-invoice = { git = "https://github.com/rust-bitcoin/rust-lightning", rev = "294009969aef617df4184ff41ef6daa5a445f213" }
-lightning-background-processor = { git = "https://github.com/rust-bitcoin/rust-lightning", rev = "294009969aef617df4184ff41ef6daa5a445f213" }
-
-[patch.crates-io]
-# Rust-Secp256k1 upstream to get PR 279 until it is released.
-secp256k1 = { git = 'https://github.com/TheBlueMatt/rust-secp256k1' }
+lightning = { git = "https://github.com/rust-bitcoin/rust-lightning", rev = "afae12ea1e610634f90335443e3fe9f126bf5551", features = ["allow_wallclock_use"] }
+lightning-persister = { git = "https://github.com/rust-bitcoin/rust-lightning", rev = "afae12ea1e610634f90335443e3fe9f126bf5551" }
+lightning-invoice = { git = "https://github.com/rust-bitcoin/rust-lightning", rev = "afae12ea1e610634f90335443e3fe9f126bf5551" }
+lightning-background-processor = { git = "https://github.com/rust-bitcoin/rust-lightning", rev = "afae12ea1e610634f90335443e3fe9f126bf5551" }
 
 # Always force panic=abort, further options are set in the genbindings.sh build script
 [profile.dev]
index b908de5dd1589f533b101272bd01f2e36582a048..b71edc324581052dc102f17d3a0dcbe331a055f2 100644 (file)
@@ -1,11 +1,17 @@
 extern "C" {
 #include <lightning.h>
+
+#ifdef REAL_NET
+#include <ldk_net.h>
+#endif
 }
 #include "include/lightningpp.hpp"
 
 #include <assert.h>
 #include <stdio.h>
 #include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include <unistd.h>
 
 #include <atomic>
@@ -193,6 +199,68 @@ void handle_event(const void *this_arg, LDKEvent event) {
        arg->events.push_back(std::move(event));
 }
 
+#ifdef REAL_NET
+class PeersConnection {
+       void* node1_handler;
+       void* node2_handler;
+
+public:
+       PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
+               node1_handler = init_socket_handling(&net1);
+               node2_handler = init_socket_handling(&net2);
+
+               struct sockaddr_in listen_addr;
+               listen_addr.sin_family = AF_INET;
+               listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
+               listen_addr.sin_port = htons(10042);
+               assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
+
+               assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
+
+               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();
+               }
+
+               // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
+               assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
+               assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
+
+               // Then disconnect the "main" connection, while another connection is being made.
+               PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
+               assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
+
+               // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
+               while (true) {
+                       PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
+                       // Wait for the peers to disconnect...
+                       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 == 0 && peers_2->datalen == 0) { break; }
+                       std::this_thread::yield();
+               }
+
+               // Finally make an actual connection and keep it this time
+               assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
+
+               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();
+               }
+       }
+       void stop() {
+               interrupt_socket_handling(node1_handler);
+               interrupt_socket_handling(node2_handler);
+       }
+};
+
+#else // REAL_NET
 
 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
        return write((int)((long)this_arg), data.data, data.datalen);
@@ -284,6 +352,7 @@ public:
                t2.join();
        }
 };
+#endif // !REAL_NET
 
 int main() {
        uint8_t channel_open_header[80];
@@ -412,14 +481,16 @@ int main() {
 
                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]);
+               LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
+               LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
                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]);
+                               LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
+                               const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
                                assert(init_feats->inner != NULL);
                                break;
                        }
@@ -486,16 +557,21 @@ int main() {
                        LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
                        if (outbound_channels->datalen == 1) {
                                const LDKChannelDetails *channel = &outbound_channels->data[0];
+                               LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
                                // 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(!memcmp(
+                                       ChannelCounterparty_get_node_id(&counterparty).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_outbound_capacity_msat(channel) ==
+                                       40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
+                               int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
+                               if (inbound_capacity < 0) inbound_capacity = 0;
+                               assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
                                assert(ChannelDetails_get_is_usable(channel));
                                break;
                        }
index 114f78928682b682079cb90712e011be59024afe..4f09cc61739236b781ac06ba9b8a1999814acd9a 100644 (file)
@@ -40,6 +40,8 @@ struct nativeRouteHintOpaque;
 typedef struct nativeRouteHintOpaque LDKnativeRouteHint;
 struct nativeRouteHintHopOpaque;
 typedef struct nativeRouteHintHopOpaque LDKnativeRouteHintHop;
+struct nativeBestBlockOpaque;
+typedef struct nativeBestBlockOpaque LDKnativeBestBlock;
 struct nativeWatchedOutputOpaque;
 typedef struct nativeWatchedOutputOpaque LDKnativeWatchedOutput;
 struct nativeInitFeaturesOpaque;
@@ -55,7 +57,6 @@ typedef struct nativeDelayedPaymentOutputDescriptorOpaque LDKnativeDelayedPaymen
 struct nativeStaticPaymentOutputDescriptorOpaque;
 typedef struct nativeStaticPaymentOutputDescriptorOpaque LDKnativeStaticPaymentOutputDescriptor;
 struct LDKBaseSign;
-typedef struct LDKBaseSign LDKBaseSign;
 struct nativeInMemorySignerOpaque;
 typedef struct nativeInMemorySignerOpaque LDKnativeInMemorySigner;
 struct nativeKeysManagerOpaque;
@@ -66,8 +67,8 @@ struct nativeChannelManagerOpaque;
 typedef struct nativeChannelManagerOpaque LDKnativeChannelManager;
 struct nativeChainParametersOpaque;
 typedef struct nativeChainParametersOpaque LDKnativeChainParameters;
-struct nativeBestBlockOpaque;
-typedef struct nativeBestBlockOpaque LDKnativeBestBlock;
+struct nativeChannelCounterpartyOpaque;
+typedef struct nativeChannelCounterpartyOpaque LDKnativeChannelCounterparty;
 struct nativeChannelDetailsOpaque;
 typedef struct nativeChannelDetailsOpaque LDKnativeChannelDetails;
 struct nativeChannelManagerReadArgsOpaque;
@@ -120,7 +121,6 @@ struct nativeErroringMessageHandlerOpaque;
 typedef struct nativeErroringMessageHandlerOpaque LDKnativeErroringMessageHandler;
 struct nativeMessageHandlerOpaque;
 typedef struct nativeMessageHandlerOpaque LDKnativeMessageHandler;
-typedef struct LDKSocketDescriptor LDKSocketDescriptor;
 struct nativePeerHandleErrorOpaque;
 typedef struct nativePeerHandleErrorOpaque LDKnativePeerHandleError;
 struct nativePeerManagerOpaque;
index 8fe104873df2a9c011bfef88e18905f7014ecb4b..55957788957f941d51f015cc93ab7242eb3a6d83 100644 (file)
@@ -210,29 +210,25 @@ typedef enum LDKIOError {
  */
 typedef enum LDKLevel {
    /**
-    *Designates logger being silent
-    */
-   LDKLevel_Off,
-   /**
-    * Designates very serious errors
+    * Designates very low priority, often extremely verbose, information
     */
-   LDKLevel_Error,
+   LDKLevel_Trace,
    /**
-    * Designates hazardous situations
+    * Designates lower priority information
     */
-   LDKLevel_Warn,
+   LDKLevel_Debug,
    /**
     * Designates useful information
     */
    LDKLevel_Info,
    /**
-    * Designates lower priority information
+    * Designates hazardous situations
     */
-   LDKLevel_Debug,
+   LDKLevel_Warn,
    /**
-    * Designates very low priority, often extremely verbose, information
+    * Designates very serious errors
     */
-   LDKLevel_Trace,
+   LDKLevel_Error,
    /**
     * Must be last for serialization purposes
     */
@@ -2209,6 +2205,11 @@ typedef enum LDKErrorAction_Tag {
     * The peer did something harmless that we weren't able to process, just log and ignore
     */
    LDKErrorAction_IgnoreError,
+   /**
+    * The peer did something harmless that we weren't able to meaningfully process.
+    * If the error is logged, log it at the given level.
+    */
+   LDKErrorAction_IgnoreAndLog,
    /**
     * The peer did something incorrect. Tell them.
     */
@@ -2237,6 +2238,9 @@ typedef struct MUST_USE_STRUCT LDKErrorAction {
    LDKErrorAction_Tag tag;
    union {
       LDKErrorAction_LDKDisconnectPeer_Body disconnect_peer;
+      struct {
+         enum LDKLevel ignore_and_log;
+      };
       LDKErrorAction_LDKSendErrorMessage_Body send_error_message;
    };
 } LDKErrorAction;
@@ -2454,6 +2458,12 @@ typedef enum LDKMessageSendEvent_Tag {
     * Used to indicate that a channel_update should be broadcast to all peers.
     */
    LDKMessageSendEvent_BroadcastChannelUpdate,
+   /**
+    * Used to indicate that a channel_update should be sent to a single peer.
+    * In contrast to [`Self::BroadcastChannelUpdate`], this is used when the channel is a
+    * private channel and we shouldn't be informing all of our peers of channel parameters.
+    */
+   LDKMessageSendEvent_SendChannelUpdate,
    /**
     * Broadcast an error downstream to be handled
     */
@@ -2629,6 +2639,17 @@ typedef struct LDKMessageSendEvent_LDKBroadcastChannelUpdate_Body {
    struct LDKChannelUpdate msg;
 } LDKMessageSendEvent_LDKBroadcastChannelUpdate_Body;
 
+typedef struct LDKMessageSendEvent_LDKSendChannelUpdate_Body {
+   /**
+    * The node_id of the node which should receive this message
+    */
+   struct LDKPublicKey node_id;
+   /**
+    * The channel_update which should be sent.
+    */
+   struct LDKChannelUpdate msg;
+} LDKMessageSendEvent_LDKSendChannelUpdate_Body;
+
 typedef struct LDKMessageSendEvent_LDKHandleError_Body {
    /**
     * The node_id of the node which should receive this message
@@ -2697,6 +2718,7 @@ typedef struct MUST_USE_STRUCT LDKMessageSendEvent {
       LDKMessageSendEvent_LDKBroadcastChannelAnnouncement_Body broadcast_channel_announcement;
       LDKMessageSendEvent_LDKBroadcastNodeAnnouncement_Body broadcast_node_announcement;
       LDKMessageSendEvent_LDKBroadcastChannelUpdate_Body broadcast_channel_update;
+      LDKMessageSendEvent_LDKSendChannelUpdate_Body send_channel_update;
       LDKMessageSendEvent_LDKHandleError_Body handle_error;
       LDKMessageSendEvent_LDKPaymentFailureNetworkUpdate_Body payment_failure_network_update;
       LDKMessageSendEvent_LDKSendChannelRangeQuery_Body send_channel_range_query;
@@ -3667,6 +3689,33 @@ typedef struct LDKCResult_CVec_C2Tuple_BlockHashChannelMonitorZZErrorZ {
    bool result_ok;
 } LDKCResult_CVec_C2Tuple_BlockHashChannelMonitorZZErrorZ;
 
+/**
+ * An enum which can either contain a u16 or not
+ */
+typedef enum LDKCOption_u16Z_Tag {
+   /**
+    * When we're in this state, this COption_u16Z contains a u16
+    */
+   LDKCOption_u16Z_Some,
+   /**
+    * When we're in this state, this COption_u16Z contains nothing
+    */
+   LDKCOption_u16Z_None,
+   /**
+    * Must be last for serialization purposes
+    */
+   LDKCOption_u16Z_Sentinel,
+} LDKCOption_u16Z_Tag;
+
+typedef struct LDKCOption_u16Z {
+   LDKCOption_u16Z_Tag tag;
+   union {
+      struct {
+         uint16_t some;
+      };
+   };
+} LDKCOption_u16Z;
+
 /**
  * Indicates an error on the client's part (usually some variant of attempting to use too-low or
  * too-high values)
@@ -7900,6 +7949,26 @@ typedef struct MUST_USE_STRUCT LDKUserConfig {
    bool is_owned;
 } LDKUserConfig;
 
+
+
+/**
+ * The best known block as identified by its hash and height.
+ */
+typedef struct MUST_USE_STRUCT LDKBestBlock {
+   /**
+    * A pointer to the opaque Rust object.
+    * Nearly everywhere, inner must be non-null, however in places where
+    * the Rust equivalent takes an Option, it may be set to null to indicate None.
+    */
+   LDKnativeBestBlock *inner;
+   /**
+    * Indicates that this is the only struct which contains the same pointer.
+    * Rust functions which take ownership of an object provided via an argument require
+    * this to be true and invalidate the object pointed to by inner.
+    */
+   bool is_owned;
+} LDKBestBlock;
+
 /**
  * The `Access` trait defines behavior for accessing chain data and state, such as blocks and
  * UTXOs.
@@ -8277,22 +8346,23 @@ typedef struct MUST_USE_STRUCT LDKChainParameters {
 
 
 /**
- * The best known block as identified by its hash and height.
+ * Channel parameters which apply to our counterparty. These are split out from [`ChannelDetails`]
+ * to better separate parameters.
  */
-typedef struct MUST_USE_STRUCT LDKBestBlock {
+typedef struct MUST_USE_STRUCT LDKChannelCounterparty {
    /**
     * A pointer to the opaque Rust object.
     * Nearly everywhere, inner must be non-null, however in places where
     * the Rust equivalent takes an Option, it may be set to null to indicate None.
     */
-   LDKnativeBestBlock *inner;
+   LDKnativeChannelCounterparty *inner;
    /**
     * Indicates that this is the only struct which contains the same pointer.
     * Rust functions which take ownership of an object provided via an argument require
     * this to be true and invalidate the object pointed to by inner.
     */
    bool is_owned;
-} LDKBestBlock;
+} LDKChannelCounterparty;
 
 /**
  * A 3-byte byte array.
@@ -8633,11 +8703,12 @@ typedef struct MUST_USE_STRUCT LDKMessageHandler {
  *
  * 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().
+ * Two descriptors may compare equal (by [`cmp::Eq`] and [`hash::Hash`]) as long as the original
+ * has been disconnected, the [`PeerManager`] has been informed of the disconnection (either by it
+ * having triggered the disconnection or a call to [`PeerManager::socket_disconnected`]), and no
+ * further calls to the [`PeerManager`] related to the original socket occur. This allows you to
+ * use a file descriptor for your SocketDescriptor directly, however for simplicity you may wish
+ * to simply use another value which is guaranteed to be globally unique instead.
  */
 typedef struct LDKSocketDescriptor {
    /**
@@ -8649,25 +8720,27 @@ typedef struct LDKSocketDescriptor {
     * 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.
+    * Note that in the disconnected case, [`PeerManager::socket_disconnected`] must still be
+    * called 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 the returned size is smaller than `data.len()`, a
+    * [`PeerManager::write_buffer_space_avail`] call must be made the next time more data can be
+    * written. Additionally, until a `send_data` event completes fully, no further
+    * [`PeerManager::read_event`] calls should be made for the same peer! Because this is to
+    * prevent denial-of-service issues, you should not read or buffer any data from the socket
+    * until then.
     *
-    * 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.
+    * If a [`PeerManager::read_event`] call 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 carries no meaning, and should not cause any action.
     */
    uintptr_t (*send_data)(void *this_arg, struct LDKu8slice data, bool resume_read);
    /**
-    * 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.
+    * Disconnect the socket pointed to by this SocketDescriptor.
+    *
+    * You do *not* need to call [`PeerManager::socket_disconnected`] with this socket after this
+    * call (doing so is a noop).
     */
    void (*disconnect_socket)(void *this_arg);
    /**
@@ -8695,14 +8768,25 @@ typedef struct LDKSocketDescriptor {
 
 
 /**
- * A PeerManager manages a set of peers, described by their SocketDescriptor and marshalls socket
- * events into messages which it passes on to its MessageHandlers.
+ * A PeerManager manages a set of peers, described by their [`SocketDescriptor`] and marshalls
+ * socket events into messages which it passes on to its [`MessageHandler`].
+ *
+ * Locks are taken internally, so you must never assume that reentrancy from a
+ * [`SocketDescriptor`] call back into [`PeerManager`] methods will not deadlock.
+ *
+ * Calls to [`read_event`] will decode relevant messages and pass them to the
+ * [`ChannelMessageHandler`], likely doing message processing in-line. Thus, the primary form of
+ * parallelism in Rust-Lightning is in calls to [`read_event`]. Note, however, that calls to any
+ * [`PeerManager`] functions related to the same connection must occur only in serial, making new
+ * calls only after previous ones have returned.
  *
  * 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.
+ *
+ * [`read_event`]: PeerManager::read_event
  */
 typedef struct MUST_USE_STRUCT LDKPeerManager {
    /**
@@ -9022,6 +9106,10 @@ extern const uint32_t MIN_FINAL_CLTV_EXPIRY;
 
 extern const uintptr_t REVOKEABLE_REDEEMSCRIPT_MAX_LENGTH;
 
+extern const uint64_t DEFAULT_EXPIRY_TIME;
+
+extern const uint64_t DEFAULT_MIN_FINAL_CLTV_EXPIRY;
+
 extern const uint8_t TAG_PAYMENT_HASH;
 
 extern const uint8_t TAG_DESCRIPTION;
@@ -9913,6 +10001,27 @@ struct LDKCResult_CVec_C2Tuple_BlockHashChannelMonitorZZErrorZ CResult_CVec_C2Tu
  */
 void CResult_CVec_C2Tuple_BlockHashChannelMonitorZZErrorZ_free(struct LDKCResult_CVec_C2Tuple_BlockHashChannelMonitorZZErrorZ _res);
 
+/**
+ * Constructs a new COption_u16Z containing a u16
+ */
+struct LDKCOption_u16Z COption_u16Z_some(uint16_t o);
+
+/**
+ * Constructs a new COption_u16Z containing nothing
+ */
+struct LDKCOption_u16Z COption_u16Z_none(void);
+
+/**
+ * Frees any resources associated with the u16, if we are in the Some state
+ */
+void COption_u16Z_free(struct LDKCOption_u16Z _res);
+
+/**
+ * Creates a new COption_u16Z which has the same data as `orig`
+ * but with all dynamically-allocated buffers duplicated in new buffers.
+ */
+struct LDKCOption_u16Z COption_u16Z_clone(const struct LDKCOption_u16Z *NONNULL_PTR orig);
+
 /**
  * Creates a new CResult_NoneAPIErrorZ in the success state.
  */
@@ -11590,7 +11699,7 @@ struct LDKAPIError APIError_clone(const struct LDKAPIError *NONNULL_PTR orig);
  * A receiver knowing the PublicKey (e.g. the node's id) and the message can be sure that the signature was generated by the caller.
  * Signatures are EC recoverable, meaning that given the message and the signature the PublicKey of the signer can be extracted.
  */
-struct LDKCResult_StringErrorZ sign(struct LDKu8slice msg, struct LDKSecretKey sk);
+struct LDKCResult_StringErrorZ sign(struct LDKu8slice msg, const uint8_t (*sk)[32]);
 
 /**
  * Recovers the PublicKey of the signer of the message given the message and the signature.
@@ -11835,20 +11944,26 @@ uint32_t ChannelHandshakeLimits_get_max_minimum_depth(const struct LDKChannelHan
 void ChannelHandshakeLimits_set_max_minimum_depth(struct LDKChannelHandshakeLimits *NONNULL_PTR this_ptr, uint32_t val);
 
 /**
- * Set to force the incoming channel to match our announced channel preference in
- * ChannelConfig.
+ * Set to force an incoming channel to match our announced channel preference in
+ * [`ChannelConfig::announced_channel`].
+ *
+ * For a node which is not online reliably, this should be set to true and
+ * [`ChannelConfig::announced_channel`] set to false, ensuring that no announced (aka public)
+ * channels will ever be opened.
  *
- * 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).
+ * Default value: true.
  */
 bool ChannelHandshakeLimits_get_force_announced_channel_preference(const struct LDKChannelHandshakeLimits *NONNULL_PTR this_ptr);
 
 /**
- * Set to force the incoming channel to match our announced channel preference in
- * ChannelConfig.
+ * Set to force an incoming channel to match our announced channel preference in
+ * [`ChannelConfig::announced_channel`].
+ *
+ * For a node which is not online reliably, this should be set to true and
+ * [`ChannelConfig::announced_channel`] set to false, ensuring that no announced (aka public)
+ * channels will ever be opened.
  *
- * 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).
+ * Default value: true.
  */
 void ChannelHandshakeLimits_set_force_announced_channel_preference(struct LDKChannelHandshakeLimits *NONNULL_PTR this_ptr, bool val);
 
@@ -11895,22 +12010,56 @@ MUST_USE_RES struct LDKChannelHandshakeLimits ChannelHandshakeLimits_default(voi
 void ChannelConfig_free(struct LDKChannelConfig this_obj);
 
 /**
- * Amount (in millionths of a satoshi) the channel will charge per transferred satoshi.
+ * Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound
+ * over the channel.
  * 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.
  */
-uint32_t ChannelConfig_get_fee_proportional_millionths(const struct LDKChannelConfig *NONNULL_PTR this_ptr);
+uint32_t ChannelConfig_get_forwarding_fee_proportional_millionths(const struct LDKChannelConfig *NONNULL_PTR this_ptr);
 
 /**
- * Amount (in millionths of a satoshi) the channel will charge per transferred satoshi.
+ * Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound
+ * over the channel.
  * 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.
  */
-void ChannelConfig_set_fee_proportional_millionths(struct LDKChannelConfig *NONNULL_PTR this_ptr, uint32_t val);
+void ChannelConfig_set_forwarding_fee_proportional_millionths(struct LDKChannelConfig *NONNULL_PTR this_ptr, uint32_t val);
+
+/**
+ * Amount (in milli-satoshi) charged for payments forwarded outbound over the channel, in
+ * excess of [`forwarding_fee_proportional_millionths`].
+ * 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.
+ *
+ * The default value of a single satoshi roughly matches the market rate on many routing nodes
+ * as of July 2021. Adjusting it upwards or downwards may change whether nodes route through
+ * this node.
+ *
+ * Default value: 1000.
+ *
+ * [`forwarding_fee_proportional_millionths`]: ChannelConfig::forwarding_fee_proportional_millionths
+ */
+uint32_t ChannelConfig_get_forwarding_fee_base_msat(const struct LDKChannelConfig *NONNULL_PTR this_ptr);
+
+/**
+ * Amount (in milli-satoshi) charged for payments forwarded outbound over the channel, in
+ * excess of [`forwarding_fee_proportional_millionths`].
+ * 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.
+ *
+ * The default value of a single satoshi roughly matches the market rate on many routing nodes
+ * as of July 2021. Adjusting it upwards or downwards may change whether nodes route through
+ * this node.
+ *
+ * Default value: 1000.
+ *
+ * [`forwarding_fee_proportional_millionths`]: ChannelConfig::forwarding_fee_proportional_millionths
+ */
+void ChannelConfig_set_forwarding_fee_base_msat(struct LDKChannelConfig *NONNULL_PTR this_ptr, uint32_t val);
 
 /**
  * The difference in the CLTV value between incoming HTLCs and an outbound HTLC forwarded over
@@ -11965,7 +12114,7 @@ void ChannelConfig_set_cltv_expiry_delta(struct LDKChannelConfig *NONNULL_PTR th
  * 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.
+ * channels unless [`ChannelHandshakeLimits::force_announced_channel_preference`] is set.
  *
  * This cannot be changed after the initial channel handshake.
  *
@@ -11980,7 +12129,7 @@ bool ChannelConfig_get_announced_channel(const struct LDKChannelConfig *NONNULL_
  * 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.
+ * channels unless [`ChannelHandshakeLimits::force_announced_channel_preference`] is set.
  *
  * This cannot be changed after the initial channel handshake.
  *
@@ -12021,7 +12170,7 @@ void ChannelConfig_set_commit_upfront_shutdown_pubkey(struct LDKChannelConfig *N
 /**
  * Constructs a new ChannelConfig given each field
  */
-MUST_USE_RES struct LDKChannelConfig ChannelConfig_new(uint32_t fee_proportional_millionths_arg, uint16_t cltv_expiry_delta_arg, bool announced_channel_arg, bool commit_upfront_shutdown_pubkey_arg);
+MUST_USE_RES struct LDKChannelConfig ChannelConfig_new(uint32_t forwarding_fee_proportional_millionths_arg, uint32_t forwarding_fee_base_msat_arg, uint16_t cltv_expiry_delta_arg, bool announced_channel_arg, bool commit_upfront_shutdown_pubkey_arg);
 
 /**
  * Creates a copy of the ChannelConfig
@@ -12078,10 +12227,50 @@ struct LDKChannelConfig UserConfig_get_channel_options(const struct LDKUserConfi
  */
 void UserConfig_set_channel_options(struct LDKUserConfig *NONNULL_PTR this_ptr, struct LDKChannelConfig val);
 
+/**
+ * If this is set to false, we will reject any HTLCs which were to be forwarded over private
+ * channels. This prevents us from taking on HTLC-forwarding risk when we intend to run as a
+ * node which is not online reliably.
+ *
+ * For nodes which are not online reliably, you should set all channels to *not* be announced
+ * (using [`ChannelConfig::announced_channel`] and
+ * [`ChannelHandshakeLimits::force_announced_channel_preference`]) and set this to false to
+ * ensure you are not exposed to any forwarding risk.
+ *
+ * Note that because you cannot change a channel's announced state after creation, there is no
+ * way to disable forwarding on public channels retroactively. Thus, in order to change a node
+ * from a publicly-announced forwarding node to a private non-forwarding node you must close
+ * all your channels and open new ones. For privacy, you should also change your node_id
+ * (swapping all private and public key material for new ones) at that time.
+ *
+ * Default value: false.
+ */
+bool UserConfig_get_accept_forwards_to_priv_channels(const struct LDKUserConfig *NONNULL_PTR this_ptr);
+
+/**
+ * If this is set to false, we will reject any HTLCs which were to be forwarded over private
+ * channels. This prevents us from taking on HTLC-forwarding risk when we intend to run as a
+ * node which is not online reliably.
+ *
+ * For nodes which are not online reliably, you should set all channels to *not* be announced
+ * (using [`ChannelConfig::announced_channel`] and
+ * [`ChannelHandshakeLimits::force_announced_channel_preference`]) and set this to false to
+ * ensure you are not exposed to any forwarding risk.
+ *
+ * Note that because you cannot change a channel's announced state after creation, there is no
+ * way to disable forwarding on public channels retroactively. Thus, in order to change a node
+ * from a publicly-announced forwarding node to a private non-forwarding node you must close
+ * all your channels and open new ones. For privacy, you should also change your node_id
+ * (swapping all private and public key material for new ones) at that time.
+ *
+ * Default value: false.
+ */
+void UserConfig_set_accept_forwards_to_priv_channels(struct LDKUserConfig *NONNULL_PTR this_ptr, bool val);
+
 /**
  * Constructs a new UserConfig given each field
  */
-MUST_USE_RES struct LDKUserConfig UserConfig_new(struct LDKChannelHandshakeConfig own_channel_config_arg, struct LDKChannelHandshakeLimits peer_channel_config_limits_arg, struct LDKChannelConfig channel_options_arg);
+MUST_USE_RES struct LDKUserConfig UserConfig_new(struct LDKChannelHandshakeConfig own_channel_config_arg, struct LDKChannelHandshakeLimits peer_channel_config_limits_arg, struct LDKChannelConfig channel_options_arg, bool accept_forwards_to_priv_channels_arg);
 
 /**
  * Creates a copy of the UserConfig
@@ -12093,6 +12282,37 @@ struct LDKUserConfig UserConfig_clone(const struct LDKUserConfig *NONNULL_PTR or
  */
 MUST_USE_RES struct LDKUserConfig UserConfig_default(void);
 
+/**
+ * Frees any resources used by the BestBlock, if is_owned is set and inner is non-NULL.
+ */
+void BestBlock_free(struct LDKBestBlock this_obj);
+
+/**
+ * Creates a copy of the BestBlock
+ */
+struct LDKBestBlock BestBlock_clone(const struct LDKBestBlock *NONNULL_PTR orig);
+
+/**
+ * Constructs a `BestBlock` that represents the genesis block at height 0 of the given
+ * network.
+ */
+MUST_USE_RES struct LDKBestBlock BestBlock_from_genesis(enum LDKNetwork network);
+
+/**
+ * Returns a `BestBlock` as identified by the given block hash and height.
+ */
+MUST_USE_RES struct LDKBestBlock BestBlock_new(struct LDKThirtyTwoBytes block_hash, uint32_t height);
+
+/**
+ * Returns the best block hash.
+ */
+MUST_USE_RES struct LDKThirtyTwoBytes BestBlock_block_hash(const struct LDKBestBlock *NONNULL_PTR this_arg);
+
+/**
+ * Returns the best block height.
+ */
+MUST_USE_RES uint32_t BestBlock_height(const struct LDKBestBlock *NONNULL_PTR this_arg);
+
 /**
  * Creates a copy of the AccessError
  */
@@ -12452,6 +12672,12 @@ MUST_USE_RES struct LDKCVec_TransactionOutputsZ ChannelMonitor_best_block_update
  */
 MUST_USE_RES struct LDKCVec_TxidZ ChannelMonitor_get_relevant_txids(const struct LDKChannelMonitor *NONNULL_PTR this_arg);
 
+/**
+ * Gets the latest best block which was connected either via the [`chain::Listen`] or
+ * [`chain::Confirm`] interfaces.
+ */
+MUST_USE_RES struct LDKBestBlock ChannelMonitor_current_best_block(const struct LDKChannelMonitor *NONNULL_PTR this_arg);
+
 /**
  * Calls the free function if one is set
  */
@@ -12987,34 +13213,60 @@ MUST_USE_RES struct LDKChainParameters ChainParameters_new(enum LDKNetwork netwo
 struct LDKChainParameters ChainParameters_clone(const struct LDKChainParameters *NONNULL_PTR orig);
 
 /**
- * Frees any resources used by the BestBlock, if is_owned is set and inner is non-NULL.
+ * Frees any resources used by the ChannelCounterparty, if is_owned is set and inner is non-NULL.
  */
-void BestBlock_free(struct LDKBestBlock this_obj);
+void ChannelCounterparty_free(struct LDKChannelCounterparty this_obj);
 
 /**
- * Creates a copy of the BestBlock
+ * The node_id of our counterparty
  */
-struct LDKBestBlock BestBlock_clone(const struct LDKBestBlock *NONNULL_PTR orig);
+struct LDKPublicKey ChannelCounterparty_get_node_id(const struct LDKChannelCounterparty *NONNULL_PTR this_ptr);
 
 /**
- * Returns the best block from the genesis of the given network.
+ * The node_id of our counterparty
  */
-MUST_USE_RES struct LDKBestBlock BestBlock_from_genesis(enum LDKNetwork network);
+void ChannelCounterparty_set_node_id(struct LDKChannelCounterparty *NONNULL_PTR this_ptr, struct LDKPublicKey val);
+
+/**
+ * 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.
+ */
+struct LDKInitFeatures ChannelCounterparty_get_features(const struct LDKChannelCounterparty *NONNULL_PTR this_ptr);
 
 /**
- * Returns the best block as identified by the given block hash and height.
+ * 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.
  */
-MUST_USE_RES struct LDKBestBlock BestBlock_new(struct LDKThirtyTwoBytes block_hash, uint32_t height);
+void ChannelCounterparty_set_features(struct LDKChannelCounterparty *NONNULL_PTR this_ptr, struct LDKInitFeatures val);
 
 /**
- * Returns the best block hash.
+ * The value, in satoshis, that must always be held in the channel for our counterparty. This
+ * value ensures that if our counterparty broadcasts a revoked state, we can punish them by
+ * claiming at least this value on chain.
+ *
+ * This value is not included in [`inbound_capacity_msat`] as it can never be spent.
+ *
+ * [`inbound_capacity_msat`]: ChannelDetails::inbound_capacity_msat
  */
-MUST_USE_RES struct LDKThirtyTwoBytes BestBlock_block_hash(const struct LDKBestBlock *NONNULL_PTR this_arg);
+uint64_t ChannelCounterparty_get_unspendable_punishment_reserve(const struct LDKChannelCounterparty *NONNULL_PTR this_ptr);
 
 /**
- * Returns the best block height.
+ * The value, in satoshis, that must always be held in the channel for our counterparty. This
+ * value ensures that if our counterparty broadcasts a revoked state, we can punish them by
+ * claiming at least this value on chain.
+ *
+ * This value is not included in [`inbound_capacity_msat`] as it can never be spent.
+ *
+ * [`inbound_capacity_msat`]: ChannelDetails::inbound_capacity_msat
  */
-MUST_USE_RES uint32_t BestBlock_height(const struct LDKBestBlock *NONNULL_PTR this_arg);
+void ChannelCounterparty_set_unspendable_punishment_reserve(struct LDKChannelCounterparty *NONNULL_PTR this_ptr, uint64_t val);
+
+/**
+ * Creates a copy of the ChannelCounterparty
+ */
+struct LDKChannelCounterparty ChannelCounterparty_clone(const struct LDKChannelCounterparty *NONNULL_PTR orig);
 
 /**
  * Frees any resources used by the ChannelDetails, if is_owned is set and inner is non-NULL.
@@ -13037,6 +13289,16 @@ const uint8_t (*ChannelDetails_get_channel_id(const struct LDKChannelDetails *NO
  */
 void ChannelDetails_set_channel_id(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKThirtyTwoBytes val);
 
+/**
+ * Parameters which apply to our counterparty. See individual fields for more information.
+ */
+struct LDKChannelCounterparty ChannelDetails_get_counterparty(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
+
+/**
+ * Parameters which apply to our counterparty. See individual fields for more information.
+ */
+void ChannelDetails_set_counterparty(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKChannelCounterparty val);
+
 /**
  * The Channel's funding transaction output, if we've negotiated the funding transaction with
  * our counterparty already.
@@ -13068,38 +13330,40 @@ struct LDKCOption_u64Z ChannelDetails_get_short_channel_id(const struct LDKChann
 void ChannelDetails_set_short_channel_id(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKCOption_u64Z val);
 
 /**
- * The node_id of our counterparty
- */
-struct LDKPublicKey ChannelDetails_get_remote_network_id(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
-
-/**
- * The node_id of our counterparty
- */
-void ChannelDetails_set_remote_network_id(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKPublicKey val);
-
-/**
- * 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.
+ * The value, in satoshis, of this channel as appears in the funding output
  */
-struct LDKInitFeatures ChannelDetails_get_counterparty_features(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
+uint64_t ChannelDetails_get_channel_value_satoshis(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
 
 /**
- * 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.
+ * The value, in satoshis, of this channel as appears in the funding output
  */
-void ChannelDetails_set_counterparty_features(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKInitFeatures val);
+void ChannelDetails_set_channel_value_satoshis(struct LDKChannelDetails *NONNULL_PTR this_ptr, uint64_t val);
 
 /**
- * The value, in satoshis, of this channel as appears in the funding output
+ * The value, in satoshis, that must always be held in the channel for us. This value ensures
+ * that if we broadcast a revoked state, our counterparty can punish us by claiming at least
+ * this value on chain.
+ *
+ * This value is not included in [`outbound_capacity_msat`] as it can never be spent.
+ *
+ * This value will be `None` for outbound channels until the counterparty accepts the channel.
+ *
+ * [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat
  */
-uint64_t ChannelDetails_get_channel_value_satoshis(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
+struct LDKCOption_u64Z ChannelDetails_get_unspendable_punishment_reserve(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
 
 /**
- * The value, in satoshis, of this channel as appears in the funding output
+ * The value, in satoshis, that must always be held in the channel for us. This value ensures
+ * that if we broadcast a revoked state, our counterparty can punish us by claiming at least
+ * this value on chain.
+ *
+ * This value is not included in [`outbound_capacity_msat`] as it can never be spent.
+ *
+ * This value will be `None` for outbound channels until the counterparty accepts the channel.
+ *
+ * [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat
  */
-void ChannelDetails_set_channel_value_satoshis(struct LDKChannelDetails *NONNULL_PTR this_ptr, uint64_t val);
+void ChannelDetails_set_unspendable_punishment_reserve(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKCOption_u64Z val);
 
 /**
  * The user_id passed in to create_channel, or 0 if the channel was inbound.
@@ -13116,6 +13380,10 @@ void ChannelDetails_set_user_id(struct LDKChannelDetails *NONNULL_PTR this_ptr,
  * 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.
+ *
+ * This value is not exact. Due to various in-flight changes, feerate changes, and our
+ * conflict-avoidance policy, exactly this amount is not likely to be spendable. However, we
+ * should be able to spend nearly this amount.
  */
 uint64_t ChannelDetails_get_outbound_capacity_msat(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
 
@@ -13124,6 +13392,10 @@ uint64_t ChannelDetails_get_outbound_capacity_msat(const struct LDKChannelDetail
  * 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.
+ *
+ * This value is not exact. Due to various in-flight changes, feerate changes, and our
+ * conflict-avoidance policy, exactly this amount is not likely to be spendable. However, we
+ * should be able to spend nearly this amount.
  */
 void ChannelDetails_set_outbound_capacity_msat(struct LDKChannelDetails *NONNULL_PTR this_ptr, uint64_t val);
 
@@ -13133,6 +13405,10 @@ void ChannelDetails_set_outbound_capacity_msat(struct LDKChannelDetails *NONNULL
  * 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.
+ *
+ * This value is not exact. Due to various in-flight changes, feerate changes, and our
+ * counterparty's conflict-avoidance policy, exactly this amount is not likely to be spendable.
+ * However, our counterparty should be able to spend nearly this amount.
  */
 uint64_t ChannelDetails_get_inbound_capacity_msat(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
 
@@ -13142,9 +13418,65 @@ uint64_t ChannelDetails_get_inbound_capacity_msat(const struct LDKChannelDetails
  * 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.
+ *
+ * This value is not exact. Due to various in-flight changes, feerate changes, and our
+ * counterparty's conflict-avoidance policy, exactly this amount is not likely to be spendable.
+ * However, our counterparty should be able to spend nearly this amount.
  */
 void ChannelDetails_set_inbound_capacity_msat(struct LDKChannelDetails *NONNULL_PTR this_ptr, uint64_t val);
 
+/**
+ * The number of required confirmations on the funding transaction before the funding will be
+ * considered \"locked\". This number is selected by the channel fundee (i.e. us if
+ * [`is_outbound`] is *not* set), and can be selected for inbound channels with
+ * [`ChannelHandshakeConfig::minimum_depth`] or limited for outbound channels with
+ * [`ChannelHandshakeLimits::max_minimum_depth`].
+ *
+ * This value will be `None` for outbound channels until the counterparty accepts the channel.
+ *
+ * [`is_outbound`]: ChannelDetails::is_outbound
+ * [`ChannelHandshakeConfig::minimum_depth`]: crate::util::config::ChannelHandshakeConfig::minimum_depth
+ * [`ChannelHandshakeLimits::max_minimum_depth`]: crate::util::config::ChannelHandshakeLimits::max_minimum_depth
+ */
+struct LDKCOption_u32Z ChannelDetails_get_confirmations_required(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
+
+/**
+ * The number of required confirmations on the funding transaction before the funding will be
+ * considered \"locked\". This number is selected by the channel fundee (i.e. us if
+ * [`is_outbound`] is *not* set), and can be selected for inbound channels with
+ * [`ChannelHandshakeConfig::minimum_depth`] or limited for outbound channels with
+ * [`ChannelHandshakeLimits::max_minimum_depth`].
+ *
+ * This value will be `None` for outbound channels until the counterparty accepts the channel.
+ *
+ * [`is_outbound`]: ChannelDetails::is_outbound
+ * [`ChannelHandshakeConfig::minimum_depth`]: crate::util::config::ChannelHandshakeConfig::minimum_depth
+ * [`ChannelHandshakeLimits::max_minimum_depth`]: crate::util::config::ChannelHandshakeLimits::max_minimum_depth
+ */
+void ChannelDetails_set_confirmations_required(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKCOption_u32Z val);
+
+/**
+ * The number of blocks (after our commitment transaction confirms) that we will need to wait
+ * until we can claim our funds after we force-close the channel. During this time our
+ * counterparty is allowed to punish us if we broadcasted a stale state. If our counterparty
+ * force-closes the channel and broadcasts a commitment transaction we do not have to wait any
+ * time to claim our non-HTLC-encumbered funds.
+ *
+ * This value will be `None` for outbound channels until the counterparty accepts the channel.
+ */
+struct LDKCOption_u16Z ChannelDetails_get_force_close_spend_delay(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
+
+/**
+ * The number of blocks (after our commitment transaction confirms) that we will need to wait
+ * until we can claim our funds after we force-close the channel. During this time our
+ * counterparty is allowed to punish us if we broadcasted a stale state. If our counterparty
+ * force-closes the channel and broadcasts a commitment transaction we do not have to wait any
+ * time to claim our non-HTLC-encumbered funds.
+ *
+ * This value will be `None` for outbound channels until the counterparty accepts the channel.
+ */
+void ChannelDetails_set_force_close_spend_delay(struct LDKChannelDetails *NONNULL_PTR this_ptr, struct LDKCOption_u16Z val);
+
 /**
  * True if the channel was initiated (and thus funded) by us.
  */
@@ -13159,7 +13491,10 @@ void ChannelDetails_set_is_outbound(struct LDKChannelDetails *NONNULL_PTR this_p
  * True if the channel is confirmed, funding_locked messages have been exchanged, and the
  * channel is not currently being shut down. `funding_locked` message exchange implies the
  * required confirmation count has been reached (and we were connected to the peer at some
- * point after the funding transaction received enough confirmations).
+ * point after the funding transaction received enough confirmations). The required
+ * confirmation count is provided in [`confirmations_required`].
+ *
+ * [`confirmations_required`]: ChannelDetails::confirmations_required
  */
 bool ChannelDetails_get_is_funding_locked(const struct LDKChannelDetails *NONNULL_PTR this_ptr);
 
@@ -13167,14 +13502,16 @@ bool ChannelDetails_get_is_funding_locked(const struct LDKChannelDetails *NONNUL
  * True if the channel is confirmed, funding_locked messages have been exchanged, and the
  * channel is not currently being shut down. `funding_locked` message exchange implies the
  * required confirmation count has been reached (and we were connected to the peer at some
- * point after the funding transaction received enough confirmations).
+ * point after the funding transaction received enough confirmations). The required
+ * confirmation count is provided in [`confirmations_required`].
+ *
+ * [`confirmations_required`]: ChannelDetails::confirmations_required
  */
 void ChannelDetails_set_is_funding_locked(struct LDKChannelDetails *NONNULL_PTR this_ptr, bool val);
 
 /**
  * True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
- * the peer is connected, (c) no monitor update failure is pending resolution, and (d) the
- * channel is not currently negotiating a shutdown.
+ * the peer is connected, and (c) the channel is not currently negotiating a shutdown.
  *
  * This is a strict superset of `is_funding_locked`.
  */
@@ -13182,8 +13519,7 @@ bool ChannelDetails_get_is_usable(const struct LDKChannelDetails *NONNULL_PTR th
 
 /**
  * True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
- * the peer is connected, (c) no monitor update failure is pending resolution, and (d) the
- * channel is not currently negotiating a shutdown.
+ * the peer is connected, and (c) the channel is not currently negotiating a shutdown.
  *
  * This is a strict superset of `is_funding_locked`.
  */
@@ -13199,6 +13535,11 @@ bool ChannelDetails_get_is_public(const struct LDKChannelDetails *NONNULL_PTR th
  */
 void ChannelDetails_set_is_public(struct LDKChannelDetails *NONNULL_PTR this_ptr, bool val);
 
+/**
+ * Constructs a new ChannelDetails given each field
+ */
+MUST_USE_RES struct LDKChannelDetails ChannelDetails_new(struct LDKThirtyTwoBytes channel_id_arg, struct LDKChannelCounterparty counterparty_arg, struct LDKOutPoint funding_txo_arg, struct LDKCOption_u64Z short_channel_id_arg, uint64_t channel_value_satoshis_arg, struct LDKCOption_u64Z unspendable_punishment_reserve_arg, uint64_t user_id_arg, uint64_t outbound_capacity_msat_arg, uint64_t inbound_capacity_msat_arg, struct LDKCOption_u32Z confirmations_required_arg, struct LDKCOption_u16Z force_close_spend_delay_arg, bool is_outbound_arg, bool is_funding_locked_arg, bool is_usable_arg, bool is_public_arg);
+
 /**
  * Creates a copy of the ChannelDetails
  */
@@ -13249,6 +13590,10 @@ MUST_USE_RES struct LDKUserConfig ChannelManager_get_current_default_configurati
  *
  * 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.
+ *
+ * Note that we do not check if you are currently connected to the given peer. If no
+ * connection is available, the outbound `open_channel` message may fail to send, resulting in
+ * the channel eventually being silently forgotten.
  */
 MUST_USE_RES struct LDKCResult_NoneAPIErrorZ ChannelManager_create_channel(const struct LDKChannelManager *NONNULL_PTR this_arg, struct LDKPublicKey their_network_key, uint64_t channel_value_satoshis, uint64_t push_msat, uint64_t user_id, struct LDKUserConfig override_config);
 
@@ -13561,6 +13906,12 @@ MUST_USE_RES bool ChannelManager_await_persistable_update_timeout(const struct L
  */
 void ChannelManager_await_persistable_update(const struct LDKChannelManager *NONNULL_PTR this_arg);
 
+/**
+ * Gets the latest best block which was connected either via the [`chain::Listen`] or
+ * [`chain::Confirm`] interfaces.
+ */
+MUST_USE_RES struct LDKBestBlock ChannelManager_current_best_block(const struct LDKChannelManager *NONNULL_PTR this_arg);
+
 /**
  * Constructs a new ChannelMessageHandler which calls the relevant methods on this_arg.
  * This copies the `inner` pointer in this_arg and thus the returned ChannelMessageHandler must be freed before this_arg is
@@ -15903,25 +16254,35 @@ void MessageHandler_free(struct LDKMessageHandler this_obj);
 
 /**
  * A message handler which handles messages specific to channels. Usually this is just a
- * ChannelManager object or a ErroringMessageHandler.
+ * [`ChannelManager`] object or an [`ErroringMessageHandler`].
+ *
+ * [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
  */
 const struct LDKChannelMessageHandler *MessageHandler_get_chan_handler(const struct LDKMessageHandler *NONNULL_PTR this_ptr);
 
 /**
  * A message handler which handles messages specific to channels. Usually this is just a
- * ChannelManager object or a ErroringMessageHandler.
+ * [`ChannelManager`] object or an [`ErroringMessageHandler`].
+ *
+ * [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
  */
 void MessageHandler_set_chan_handler(struct LDKMessageHandler *NONNULL_PTR this_ptr, struct LDKChannelMessageHandler val);
 
 /**
  * A message handler which handles messages updating our knowledge of the network channel
- * graph. Usually this is just a NetGraphMsgHandlerMonitor object or an IgnoringMessageHandler.
+ * graph. Usually this is just a [`NetGraphMsgHandler`] object or an
+ * [`IgnoringMessageHandler`].
+ *
+ * [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler
  */
 const struct LDKRoutingMessageHandler *MessageHandler_get_route_handler(const struct LDKMessageHandler *NONNULL_PTR this_ptr);
 
 /**
  * A message handler which handles messages updating our knowledge of the network channel
- * graph. Usually this is just a NetGraphMsgHandlerMonitor object or an IgnoringMessageHandler.
+ * graph. Usually this is just a [`NetGraphMsgHandler`] object or an
+ * [`IgnoringMessageHandler`].
+ *
+ * [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler
  */
 void MessageHandler_set_route_handler(struct LDKMessageHandler *NONNULL_PTR this_ptr, struct LDKRoutingMessageHandler val);
 
@@ -15995,8 +16356,10 @@ MUST_USE_RES struct LDKCVec_PublicKeyZ PeerManager_get_peer_node_ids(const struc
  *
  * 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().
+ * Panics if descriptor is duplicative with some other descriptor which has not yet been
+ * [`socket_disconnected()`].
+ *
+ * [`socket_disconnected()`]: PeerManager::socket_disconnected
  */
 MUST_USE_RES struct LDKCResult_CVec_u8ZPeerHandleErrorZ PeerManager_new_outbound_connection(const struct LDKPeerManager *NONNULL_PTR this_arg, struct LDKPublicKey their_node_id, struct LDKSocketDescriptor descriptor);
 
@@ -16008,8 +16371,10 @@ MUST_USE_RES struct LDKCResult_CVec_u8ZPeerHandleErrorZ PeerManager_new_outbound
  * 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.
+ * Panics if descriptor is duplicative with some other descriptor which has not yet been
+ * [`socket_disconnected()`].
+ *
+ * [`socket_disconnected()`]: PeerManager::socket_disconnected
  */
 MUST_USE_RES struct LDKCResult_NonePeerHandleErrorZ PeerManager_new_inbound_connection(const struct LDKPeerManager *NONNULL_PTR this_arg, struct LDKSocketDescriptor descriptor);
 
@@ -16018,12 +16383,14 @@ MUST_USE_RES struct LDKCResult_NonePeerHandleErrorZ PeerManager_new_inbound_conn
  *
  * 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.
+ * May call [`send_data`] on the descriptor passed in (or an equal descriptor) 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!
+ *
+ * [`send_data`]: SocketDescriptor::send_data
+ * [`write_buffer_space_avail`]: PeerManager::write_buffer_space_avail
  */
 MUST_USE_RES struct LDKCResult_NonePeerHandleErrorZ PeerManager_write_buffer_space_avail(const struct LDKPeerManager *NONNULL_PTR this_arg, struct LDKSocketDescriptor *NONNULL_PTR descriptor);
 
@@ -16032,51 +16399,60 @@ MUST_USE_RES struct LDKCResult_NonePeerHandleErrorZ PeerManager_write_buffer_spa
  *
  * 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.
+ * Will *not* call back into [`send_data`] on any descriptors to avoid reentrancy complexity.
+ * Thus, however, you should 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).
+ * If `Ok(true)` is returned, further read_events should not be triggered until a
+ * [`send_data`] call on this 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.
+ * [`send_data`]: SocketDescriptor::send_data
+ * [`process_events`]: PeerManager::process_events
  */
 MUST_USE_RES struct LDKCResult_boolPeerHandleErrorZ PeerManager_read_event(const struct LDKPeerManager *NONNULL_PTR this_arg, struct LDKSocketDescriptor *NONNULL_PTR peer_descriptor, struct LDKu8slice data);
 
 /**
  * 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).
+ * functions like [`ChannelManager::process_pending_htlc_forwards`] or [`send_payment`]).
+ *
+ * May call [`send_data`] on [`SocketDescriptor`]s. Thus, be very careful with reentrancy
+ * issues!
+ *
+ * [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
+ * [`ChannelManager::process_pending_htlc_forwards`]: crate::ln::channelmanager::ChannelManager::process_pending_htlc_forwards
+ * [`send_data`]: SocketDescriptor::send_data
  */
 void PeerManager_process_events(const struct LDKPeerManager *NONNULL_PTR this_arg);
 
 /**
  * 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.
  */
 void PeerManager_socket_disconnected(const struct LDKPeerManager *NONNULL_PTR this_arg, const struct LDKSocketDescriptor *NONNULL_PTR descriptor);
 
 /**
  * Disconnect a peer given its node id.
  *
- * Set no_connection_possible to true to prevent any further connection with this peer,
+ * Set `no_connection_possible` to true to prevent any further connection with this peer,
  * force-closing any channels we have with it.
  *
- * If a peer is connected, this will call `disconnect_socket` on the descriptor for the peer,
- * so be careful about reentrancy issues.
+ * If a peer is connected, this will call [`disconnect_socket`] on the descriptor for the
+ * peer. Thus, be very careful about reentrancy issues.
+ *
+ * [`disconnect_socket`]: SocketDescriptor::disconnect_socket
  */
 void PeerManager_disconnect_by_node_id(const struct LDKPeerManager *NONNULL_PTR this_arg, struct LDKPublicKey node_id, bool no_connection_possible);
 
 /**
  * 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!
+ * It will send pings to each peer and disconnect those which did not respond to the last
+ * round of pings.
+ *
+ * May call [`send_data`] on all [`SocketDescriptor`]s. Thus, be very careful with reentrancy
+ * issues!
+ *
+ * [`send_data`]: SocketDescriptor::send_data
  */
 void PeerManager_timer_tick_occurred(const struct LDKPeerManager *NONNULL_PTR this_arg);
 
index 0b0a417e64c860f27ac653476dcb6ac080a22cc5..e59512b0c400aae4cccf072acec4191b65cc0926 100644 (file)
@@ -284,6 +284,21 @@ public:
        const LDKFeeEstimator* operator &() const { return &self; }
        const LDKFeeEstimator* operator ->() const { return &self; }
 };
+class BestBlock {
+private:
+       LDKBestBlock self;
+public:
+       BestBlock(const BestBlock&) = delete;
+       BestBlock(BestBlock&& o) : self(o.self) { memset(&o, 0, sizeof(BestBlock)); }
+       BestBlock(LDKBestBlock&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKBestBlock)); }
+       operator LDKBestBlock() && { LDKBestBlock res = self; memset(&self, 0, sizeof(LDKBestBlock)); return res; }
+       ~BestBlock() { BestBlock_free(self); }
+       BestBlock& operator=(BestBlock&& o) { BestBlock_free(self); self = o.self; memset(&o, 0, sizeof(BestBlock)); return *this; }
+       LDKBestBlock* operator &() { return &self; }
+       LDKBestBlock* operator ->() { return &self; }
+       const LDKBestBlock* operator &() const { return &self; }
+       const LDKBestBlock* operator ->() const { return &self; }
+};
 class AccessError {
 private:
        LDKAccessError self;
@@ -688,20 +703,20 @@ public:
        const LDKChainParameters* operator &() const { return &self; }
        const LDKChainParameters* operator ->() const { return &self; }
 };
-class BestBlock {
+class ChannelCounterparty {
 private:
-       LDKBestBlock self;
+       LDKChannelCounterparty self;
 public:
-       BestBlock(const BestBlock&) = delete;
-       BestBlock(BestBlock&& o) : self(o.self) { memset(&o, 0, sizeof(BestBlock)); }
-       BestBlock(LDKBestBlock&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKBestBlock)); }
-       operator LDKBestBlock() && { LDKBestBlock res = self; memset(&self, 0, sizeof(LDKBestBlock)); return res; }
-       ~BestBlock() { BestBlock_free(self); }
-       BestBlock& operator=(BestBlock&& o) { BestBlock_free(self); self = o.self; memset(&o, 0, sizeof(BestBlock)); return *this; }
-       LDKBestBlock* operator &() { return &self; }
-       LDKBestBlock* operator ->() { return &self; }
-       const LDKBestBlock* operator &() const { return &self; }
-       const LDKBestBlock* operator ->() const { return &self; }
+       ChannelCounterparty(const ChannelCounterparty&) = delete;
+       ChannelCounterparty(ChannelCounterparty&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelCounterparty)); }
+       ChannelCounterparty(LDKChannelCounterparty&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelCounterparty)); }
+       operator LDKChannelCounterparty() && { LDKChannelCounterparty res = self; memset(&self, 0, sizeof(LDKChannelCounterparty)); return res; }
+       ~ChannelCounterparty() { ChannelCounterparty_free(self); }
+       ChannelCounterparty& operator=(ChannelCounterparty&& o) { ChannelCounterparty_free(self); self = o.self; memset(&o, 0, sizeof(ChannelCounterparty)); return *this; }
+       LDKChannelCounterparty* operator &() { return &self; }
+       LDKChannelCounterparty* operator ->() { return &self; }
+       const LDKChannelCounterparty* operator &() const { return &self; }
+       const LDKChannelCounterparty* operator ->() const { return &self; }
 };
 class ChannelDetails {
 private:
@@ -3517,6 +3532,21 @@ public:
        const LDKCVec_RouteHintZ* operator &() const { return &self; }
        const LDKCVec_RouteHintZ* operator ->() const { return &self; }
 };
+class COption_u16Z {
+private:
+       LDKCOption_u16Z self;
+public:
+       COption_u16Z(const COption_u16Z&) = delete;
+       COption_u16Z(COption_u16Z&& o) : self(o.self) { memset(&o, 0, sizeof(COption_u16Z)); }
+       COption_u16Z(LDKCOption_u16Z&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCOption_u16Z)); }
+       operator LDKCOption_u16Z() && { LDKCOption_u16Z res = self; memset(&self, 0, sizeof(LDKCOption_u16Z)); return res; }
+       ~COption_u16Z() { COption_u16Z_free(self); }
+       COption_u16Z& operator=(COption_u16Z&& o) { COption_u16Z_free(self); self = o.self; memset(&o, 0, sizeof(COption_u16Z)); return *this; }
+       LDKCOption_u16Z* operator &() { return &self; }
+       LDKCOption_u16Z* operator ->() { return &self; }
+       const LDKCOption_u16Z* operator &() const { return &self; }
+       const LDKCOption_u16Z* operator ->() const { return &self; }
+};
 class CVec_CVec_RouteHopZZ {
 private:
        LDKCVec_CVec_RouteHopZZ self;
index 33325e2539e0ccd77c66e9a00d2e62138211ab16..c9d57ee472888560d5a470b9ee28c8168970690a 100644 (file)
@@ -3790,6 +3790,40 @@ impl From<crate::c_types::CResultTempl<crate::c_types::derived::CVec_C2Tuple_Blo
        }
 }
 #[repr(C)]
+#[derive(Clone)]
+/// An enum which can either contain a u16 or not
+pub enum COption_u16Z {
+       /// When we're in this state, this COption_u16Z contains a u16
+       Some(u16),
+       /// When we're in this state, this COption_u16Z contains nothing
+       None
+}
+impl COption_u16Z {
+       #[allow(unused)] pub(crate) fn is_some(&self) -> bool {
+               if let Self::Some(_) = self { true } else { false }
+       }
+       #[allow(unused)] pub(crate) fn take(mut self) -> u16 {
+               if let Self::Some(v) = self { v } else { unreachable!() }
+       }
+}
+#[no_mangle]
+/// Constructs a new COption_u16Z containing a u16
+pub extern "C" fn COption_u16Z_some(o: u16) -> COption_u16Z {
+       COption_u16Z::Some(o)
+}
+#[no_mangle]
+/// Constructs a new COption_u16Z containing nothing
+pub extern "C" fn COption_u16Z_none() -> COption_u16Z {
+       COption_u16Z::None
+}
+#[no_mangle]
+/// Frees any resources associated with the u16, if we are in the Some state
+pub extern "C" fn COption_u16Z_free(_res: COption_u16Z) { }
+#[no_mangle]
+/// Creates a new COption_u16Z which has the same data as `orig`
+/// but with all dynamically-allocated buffers duplicated in new buffers.
+pub extern "C" fn COption_u16Z_clone(orig: &COption_u16Z) -> COption_u16Z { orig.clone() }
+#[repr(C)]
 /// The contents of CResult_NoneAPIErrorZ
 pub union CResult_NoneAPIErrorZPtr {
        /// Note that this value is always NULL, as there are no contents in the OK variant
index 1331506e033bbff55b2809c499c100488221aa48..a5429bcba4a320ae57653cffbe18ea64843e1b1c 100644 (file)
@@ -720,6 +720,15 @@ pub extern "C" fn ChannelMonitor_get_relevant_txids(this_arg: &ChannelMonitor) -
        local_ret.into()
 }
 
+/// Gets the latest best block which was connected either via the [`chain::Listen`] or
+/// [`chain::Confirm`] interfaces.
+#[must_use]
+#[no_mangle]
+pub extern "C" fn ChannelMonitor_current_best_block(this_arg: &ChannelMonitor) -> crate::lightning::chain::BestBlock {
+       let mut ret = unsafe { &*this_arg.inner }.current_best_block();
+       crate::lightning::chain::BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true }
+}
+
 /// `Persist` defines behavior for persisting channel monitors: this could mean
 /// writing once to disk, and/or uploading to one or more backup services.
 ///
index 4879e7f6aacf660d4ff43838ddf6474e25cbc355..21a6b8ad78ba92654663f021c909342e670815eb 100644 (file)
@@ -34,6 +34,103 @@ use bitcoin::hashes::Hash;
 use crate::c_types::*;
 
 }
+
+use lightning::chain::BestBlock as nativeBestBlockImport;
+type nativeBestBlock = nativeBestBlockImport;
+
+/// The best known block as identified by its hash and height.
+#[must_use]
+#[repr(C)]
+pub struct BestBlock {
+       /// A pointer to the opaque Rust object.
+
+       /// Nearly everywhere, inner must be non-null, however in places where
+       /// the Rust equivalent takes an Option, it may be set to null to indicate None.
+       pub inner: *mut nativeBestBlock,
+       /// Indicates that this is the only struct which contains the same pointer.
+
+       /// Rust functions which take ownership of an object provided via an argument require
+       /// this to be true and invalidate the object pointed to by inner.
+       pub is_owned: bool,
+}
+
+impl Drop for BestBlock {
+       fn drop(&mut self) {
+               if self.is_owned && !<*mut nativeBestBlock>::is_null(self.inner) {
+                       let _ = unsafe { Box::from_raw(self.inner) };
+               }
+       }
+}
+/// Frees any resources used by the BestBlock, if is_owned is set and inner is non-NULL.
+#[no_mangle]
+pub extern "C" fn BestBlock_free(this_obj: BestBlock) { }
+#[allow(unused)]
+/// Used only if an object of this type is returned as a trait impl by a method
+extern "C" fn BestBlock_free_void(this_ptr: *mut c_void) {
+       unsafe { let _ = Box::from_raw(this_ptr as *mut nativeBestBlock); }
+}
+#[allow(unused)]
+/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
+impl BestBlock {
+       pub(crate) fn take_inner(mut self) -> *mut nativeBestBlock {
+               assert!(self.is_owned);
+               let ret = self.inner;
+               self.inner = std::ptr::null_mut();
+               ret
+       }
+}
+impl Clone for BestBlock {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: if <*mut nativeBestBlock>::is_null(self.inner) { std::ptr::null_mut() } else {
+                               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 BestBlock_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeBestBlock)).clone() })) as *mut c_void
+}
+#[no_mangle]
+/// Creates a copy of the BestBlock
+pub extern "C" fn BestBlock_clone(orig: &BestBlock) -> BestBlock {
+       orig.clone()
+}
+/// Constructs a `BestBlock` that represents the genesis block at height 0 of the given
+/// network.
+#[must_use]
+#[no_mangle]
+pub extern "C" fn BestBlock_from_genesis(mut network: crate::bitcoin::network::Network) -> BestBlock {
+       let mut ret = lightning::chain::BestBlock::from_genesis(network.into_bitcoin());
+       BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true }
+}
+
+/// Returns a `BestBlock` as identified by the given block hash and height.
+#[must_use]
+#[no_mangle]
+pub extern "C" fn BestBlock_new(mut block_hash: crate::c_types::ThirtyTwoBytes, mut height: u32) -> BestBlock {
+       let mut ret = lightning::chain::BestBlock::new(::bitcoin::hash_types::BlockHash::from_slice(&block_hash.data[..]).unwrap(), height);
+       BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true }
+}
+
+/// Returns the best block hash.
+#[must_use]
+#[no_mangle]
+pub extern "C" fn BestBlock_block_hash(this_arg: &BestBlock) -> crate::c_types::ThirtyTwoBytes {
+       let mut ret = unsafe { &*this_arg.inner }.block_hash();
+       crate::c_types::ThirtyTwoBytes { data: ret.into_inner() }
+}
+
+/// Returns the best block height.
+#[must_use]
+#[no_mangle]
+pub extern "C" fn BestBlock_height(this_arg: &BestBlock) -> u32 {
+       let mut ret = unsafe { &*this_arg.inner }.height();
+       ret
+}
+
 /// An error when accessing the chain via [`Access`].
 #[must_use]
 #[derive(Clone)]
index 164e944bff7277a91167176960de02e5f7887109..62b675e076969162474168a514915172da21496f 100644 (file)
@@ -166,21 +166,21 @@ pub extern "C" fn ChainParameters_set_network(this_ptr: &mut ChainParameters, mu
 ///
 /// Used to track on-chain channel funding outputs and send payments with reliable timelocks.
 #[no_mangle]
-pub extern "C" fn ChainParameters_get_best_block(this_ptr: &ChainParameters) -> crate::lightning::ln::channelmanager::BestBlock {
+pub extern "C" fn ChainParameters_get_best_block(this_ptr: &ChainParameters) -> crate::lightning::chain::BestBlock {
        let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.best_block;
-       crate::lightning::ln::channelmanager::BestBlock { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false }
+       crate::lightning::chain::BestBlock { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false }
 }
 /// The hash and height of the latest block successfully connected.
 ///
 /// Used to track on-chain channel funding outputs and send payments with reliable timelocks.
 #[no_mangle]
-pub extern "C" fn ChainParameters_set_best_block(this_ptr: &mut ChainParameters, mut val: crate::lightning::ln::channelmanager::BestBlock) {
+pub extern "C" fn ChainParameters_set_best_block(this_ptr: &mut ChainParameters, mut val: crate::lightning::chain::BestBlock) {
        unsafe { &mut *this_ptr.inner }.best_block = *unsafe { Box::from_raw(val.take_inner()) };
 }
 /// Constructs a new ChainParameters given each field
 #[must_use]
 #[no_mangle]
-pub extern "C" fn ChainParameters_new(mut network_arg: crate::bitcoin::network::Network, mut best_block_arg: crate::lightning::ln::channelmanager::BestBlock) -> ChainParameters {
+pub extern "C" fn ChainParameters_new(mut network_arg: crate::bitcoin::network::Network, mut best_block_arg: crate::lightning::chain::BestBlock) -> ChainParameters {
        ChainParameters { inner: Box::into_raw(Box::new(nativeChainParameters {
                network: network_arg.into_bitcoin(),
                best_block: *unsafe { Box::from_raw(best_block_arg.take_inner()) },
@@ -205,19 +205,44 @@ pub(crate) extern "C" fn ChainParameters_clone_void(this_ptr: *const c_void) ->
 pub extern "C" fn ChainParameters_clone(orig: &ChainParameters) -> ChainParameters {
        orig.clone()
 }
+/// The amount of time in blocks we require our counterparty wait to claim their money (ie time
+/// between when we, or our watchtower, must check for them having broadcast a theft transaction).
+///
+/// This can be increased (but not decreased) through [`ChannelHandshakeConfig::our_to_self_delay`]
+///
+/// [`ChannelHandshakeConfig::our_to_self_delay`]: crate::util::config::ChannelHandshakeConfig::our_to_self_delay
+
+#[no_mangle]
+pub static BREAKDOWN_TIMEOUT: u16 = lightning::ln::channelmanager::BREAKDOWN_TIMEOUT;
+/// The minimum number of blocks between an inbound HTLC's CLTV and the corresponding outbound
+/// HTLC's CLTV. The current default represents roughly seven hours of blocks at six blocks/hour.
+///
+/// This can be increased (but not decreased) through [`ChannelConfig::cltv_expiry_delta`]
+///
+/// [`ChannelConfig::cltv_expiry_delta`]: crate::util::config::ChannelConfig::cltv_expiry_delta
 
-use lightning::ln::channelmanager::BestBlock as nativeBestBlockImport;
-type nativeBestBlock = nativeBestBlockImport;
+#[no_mangle]
+pub static MIN_CLTV_EXPIRY_DELTA: u16 = lightning::ln::channelmanager::MIN_CLTV_EXPIRY_DELTA;
+/// Minimum CLTV difference between the current block height and received inbound payments.
+/// Invoices generated for payment to us must set their `min_final_cltv_expiry` field to at least
+/// this value.
 
-/// The best known block as identified by its hash and height.
+#[no_mangle]
+pub static MIN_FINAL_CLTV_EXPIRY: u32 = lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY;
+
+use lightning::ln::channelmanager::ChannelCounterparty as nativeChannelCounterpartyImport;
+type nativeChannelCounterparty = nativeChannelCounterpartyImport;
+
+/// Channel parameters which apply to our counterparty. These are split out from [`ChannelDetails`]
+/// to better separate parameters.
 #[must_use]
 #[repr(C)]
-pub struct BestBlock {
+pub struct ChannelCounterparty {
        /// A pointer to the opaque Rust object.
 
        /// Nearly everywhere, inner must be non-null, however in places where
        /// the Rust equivalent takes an Option, it may be set to null to indicate None.
-       pub inner: *mut nativeBestBlock,
+       pub inner: *mut nativeChannelCounterparty,
        /// Indicates that this is the only struct which contains the same pointer.
 
        /// Rust functions which take ownership of an object provided via an argument require
@@ -225,106 +250,99 @@ pub struct BestBlock {
        pub is_owned: bool,
 }
 
-impl Drop for BestBlock {
+impl Drop for ChannelCounterparty {
        fn drop(&mut self) {
-               if self.is_owned && !<*mut nativeBestBlock>::is_null(self.inner) {
+               if self.is_owned && !<*mut nativeChannelCounterparty>::is_null(self.inner) {
                        let _ = unsafe { Box::from_raw(self.inner) };
                }
        }
 }
-/// Frees any resources used by the BestBlock, if is_owned is set and inner is non-NULL.
+/// Frees any resources used by the ChannelCounterparty, if is_owned is set and inner is non-NULL.
 #[no_mangle]
-pub extern "C" fn BestBlock_free(this_obj: BestBlock) { }
+pub extern "C" fn ChannelCounterparty_free(this_obj: ChannelCounterparty) { }
 #[allow(unused)]
 /// Used only if an object of this type is returned as a trait impl by a method
-extern "C" fn BestBlock_free_void(this_ptr: *mut c_void) {
-       unsafe { let _ = Box::from_raw(this_ptr as *mut nativeBestBlock); }
+extern "C" fn ChannelCounterparty_free_void(this_ptr: *mut c_void) {
+       unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelCounterparty); }
 }
 #[allow(unused)]
 /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
-impl BestBlock {
-       pub(crate) fn take_inner(mut self) -> *mut nativeBestBlock {
+impl ChannelCounterparty {
+       pub(crate) fn take_inner(mut self) -> *mut nativeChannelCounterparty {
                assert!(self.is_owned);
                let ret = self.inner;
                self.inner = std::ptr::null_mut();
                ret
        }
 }
-impl Clone for BestBlock {
-       fn clone(&self) -> Self {
-               Self {
-                       inner: if <*mut nativeBestBlock>::is_null(self.inner) { std::ptr::null_mut() } else {
-                               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 BestBlock_clone_void(this_ptr: *const c_void) -> *mut c_void {
-       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeBestBlock)).clone() })) as *mut c_void
-}
-#[no_mangle]
-/// Creates a copy of the BestBlock
-pub extern "C" fn BestBlock_clone(orig: &BestBlock) -> BestBlock {
-       orig.clone()
-}
-/// Returns the best block from the genesis of the given network.
-#[must_use]
+/// The node_id of our counterparty
 #[no_mangle]
-pub extern "C" fn BestBlock_from_genesis(mut network: crate::bitcoin::network::Network) -> BestBlock {
-       let mut ret = lightning::ln::channelmanager::BestBlock::from_genesis(network.into_bitcoin());
-       BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true }
+pub extern "C" fn ChannelCounterparty_get_node_id(this_ptr: &ChannelCounterparty) -> crate::c_types::PublicKey {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.node_id;
+       crate::c_types::PublicKey::from_rust(&inner_val)
 }
-
-/// Returns the best block as identified by the given block hash and height.
-#[must_use]
+/// The node_id of our counterparty
 #[no_mangle]
-pub extern "C" fn BestBlock_new(mut block_hash: crate::c_types::ThirtyTwoBytes, mut height: u32) -> BestBlock {
-       let mut ret = lightning::ln::channelmanager::BestBlock::new(::bitcoin::hash_types::BlockHash::from_slice(&block_hash.data[..]).unwrap(), height);
-       BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true }
+pub extern "C" fn ChannelCounterparty_set_node_id(this_ptr: &mut ChannelCounterparty, mut val: crate::c_types::PublicKey) {
+       unsafe { &mut *this_ptr.inner }.node_id = val.into_rust();
 }
-
-/// Returns the best block hash.
-#[must_use]
+/// 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 BestBlock_block_hash(this_arg: &BestBlock) -> crate::c_types::ThirtyTwoBytes {
-       let mut ret = unsafe { &*this_arg.inner }.block_hash();
-       crate::c_types::ThirtyTwoBytes { data: ret.into_inner() }
+pub extern "C" fn ChannelCounterparty_get_features(this_ptr: &ChannelCounterparty) -> crate::lightning::ln::features::InitFeatures {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.features;
+       crate::lightning::ln::features::InitFeatures { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false }
 }
-
-/// Returns the best block height.
-#[must_use]
+/// 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 BestBlock_height(this_arg: &BestBlock) -> u32 {
-       let mut ret = unsafe { &*this_arg.inner }.height();
-       ret
+pub extern "C" fn ChannelCounterparty_set_features(this_ptr: &mut ChannelCounterparty, mut val: crate::lightning::ln::features::InitFeatures) {
+       unsafe { &mut *this_ptr.inner }.features = *unsafe { Box::from_raw(val.take_inner()) };
 }
-
-/// The amount of time in blocks we require our counterparty wait to claim their money (ie time
-/// between when we, or our watchtower, must check for them having broadcast a theft transaction).
+/// The value, in satoshis, that must always be held in the channel for our counterparty. This
+/// value ensures that if our counterparty broadcasts a revoked state, we can punish them by
+/// claiming at least this value on chain.
 ///
-/// This can be increased (but not decreased) through [`ChannelHandshakeConfig::our_to_self_delay`]
+/// This value is not included in [`inbound_capacity_msat`] as it can never be spent.
 ///
-/// [`ChannelHandshakeConfig::our_to_self_delay`]: crate::util::config::ChannelHandshakeConfig::our_to_self_delay
-
+/// [`inbound_capacity_msat`]: ChannelDetails::inbound_capacity_msat
 #[no_mangle]
-pub static BREAKDOWN_TIMEOUT: u16 = lightning::ln::channelmanager::BREAKDOWN_TIMEOUT;
-/// The minimum number of blocks between an inbound HTLC's CLTV and the corresponding outbound
-/// HTLC's CLTV. The current default represents roughly seven hours of blocks at six blocks/hour.
+pub extern "C" fn ChannelCounterparty_get_unspendable_punishment_reserve(this_ptr: &ChannelCounterparty) -> u64 {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.unspendable_punishment_reserve;
+       *inner_val
+}
+/// The value, in satoshis, that must always be held in the channel for our counterparty. This
+/// value ensures that if our counterparty broadcasts a revoked state, we can punish them by
+/// claiming at least this value on chain.
 ///
-/// This can be increased (but not decreased) through [`ChannelConfig::cltv_expiry_delta`]
+/// This value is not included in [`inbound_capacity_msat`] as it can never be spent.
 ///
-/// [`ChannelConfig::cltv_expiry_delta`]: crate::util::config::ChannelConfig::cltv_expiry_delta
-
+/// [`inbound_capacity_msat`]: ChannelDetails::inbound_capacity_msat
 #[no_mangle]
-pub static MIN_CLTV_EXPIRY_DELTA: u16 = lightning::ln::channelmanager::MIN_CLTV_EXPIRY_DELTA;
-/// Minimum CLTV difference between the current block height and received inbound payments.
-/// Invoices generated for payment to us must set their `min_final_cltv_expiry` field to at least
-/// this value.
-
+pub extern "C" fn ChannelCounterparty_set_unspendable_punishment_reserve(this_ptr: &mut ChannelCounterparty, mut val: u64) {
+       unsafe { &mut *this_ptr.inner }.unspendable_punishment_reserve = val;
+}
+impl Clone for ChannelCounterparty {
+       fn clone(&self) -> Self {
+               Self {
+                       inner: if <*mut nativeChannelCounterparty>::is_null(self.inner) { std::ptr::null_mut() } else {
+                               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 ChannelCounterparty_clone_void(this_ptr: *const c_void) -> *mut c_void {
+       Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelCounterparty)).clone() })) as *mut c_void
+}
 #[no_mangle]
-pub static MIN_FINAL_CLTV_EXPIRY: u32 = lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY;
+/// Creates a copy of the ChannelCounterparty
+pub extern "C" fn ChannelCounterparty_clone(orig: &ChannelCounterparty) -> ChannelCounterparty {
+       orig.clone()
+}
 
 use lightning::ln::channelmanager::ChannelDetails as nativeChannelDetailsImport;
 type nativeChannelDetails = nativeChannelDetailsImport;
@@ -387,6 +405,17 @@ pub extern "C" fn ChannelDetails_get_channel_id(this_ptr: &ChannelDetails) -> *c
 pub extern "C" fn ChannelDetails_set_channel_id(this_ptr: &mut ChannelDetails, mut val: crate::c_types::ThirtyTwoBytes) {
        unsafe { &mut *this_ptr.inner }.channel_id = val.data;
 }
+/// Parameters which apply to our counterparty. See individual fields for more information.
+#[no_mangle]
+pub extern "C" fn ChannelDetails_get_counterparty(this_ptr: &ChannelDetails) -> crate::lightning::ln::channelmanager::ChannelCounterparty {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.counterparty;
+       crate::lightning::ln::channelmanager::ChannelCounterparty { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false }
+}
+/// Parameters which apply to our counterparty. See individual fields for more information.
+#[no_mangle]
+pub extern "C" fn ChannelDetails_set_counterparty(this_ptr: &mut ChannelDetails, mut val: crate::lightning::ln::channelmanager::ChannelCounterparty) {
+       unsafe { &mut *this_ptr.inner }.counterparty = *unsafe { Box::from_raw(val.take_inner()) };
+}
 /// The Channel's funding transaction output, if we've negotiated the funding transaction with
 /// our counterparty already.
 ///
@@ -423,32 +452,6 @@ pub extern "C" fn ChannelDetails_set_short_channel_id(this_ptr: &mut ChannelDeta
        let mut local_val = if val.is_some() { Some( { val.take() }) } else { None };
        unsafe { &mut *this_ptr.inner }.short_channel_id = local_val;
 }
-/// 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::lightning::ln::features::InitFeatures {
-       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.counterparty_features;
-       crate::lightning::ln::features::InitFeatures { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, 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::lightning::ln::features::InitFeatures) {
-       unsafe { &mut *this_ptr.inner }.counterparty_features = *unsafe { Box::from_raw(val.take_inner()) };
-}
 /// 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 {
@@ -460,6 +463,35 @@ pub extern "C" fn ChannelDetails_get_channel_value_satoshis(this_ptr: &ChannelDe
 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 value, in satoshis, that must always be held in the channel for us. This value ensures
+/// that if we broadcast a revoked state, our counterparty can punish us by claiming at least
+/// this value on chain.
+///
+/// This value is not included in [`outbound_capacity_msat`] as it can never be spent.
+///
+/// This value will be `None` for outbound channels until the counterparty accepts the channel.
+///
+/// [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat
+#[no_mangle]
+pub extern "C" fn ChannelDetails_get_unspendable_punishment_reserve(this_ptr: &ChannelDetails) -> crate::c_types::derived::COption_u64Z {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.unspendable_punishment_reserve;
+       let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_u64Z::None } else {  { crate::c_types::derived::COption_u64Z::Some(inner_val.unwrap()) } };
+       local_inner_val
+}
+/// The value, in satoshis, that must always be held in the channel for us. This value ensures
+/// that if we broadcast a revoked state, our counterparty can punish us by claiming at least
+/// this value on chain.
+///
+/// This value is not included in [`outbound_capacity_msat`] as it can never be spent.
+///
+/// This value will be `None` for outbound channels until the counterparty accepts the channel.
+///
+/// [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat
+#[no_mangle]
+pub extern "C" fn ChannelDetails_set_unspendable_punishment_reserve(this_ptr: &mut ChannelDetails, mut val: crate::c_types::derived::COption_u64Z) {
+       let mut local_val = if val.is_some() { Some( { val.take() }) } else { None };
+       unsafe { &mut *this_ptr.inner }.unspendable_punishment_reserve = local_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 {
@@ -475,6 +507,10 @@ pub extern "C" fn ChannelDetails_set_user_id(this_ptr: &mut ChannelDetails, mut
 /// 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.
+///
+/// This value is not exact. Due to various in-flight changes, feerate changes, and our
+/// conflict-avoidance policy, exactly this amount is not likely to be spendable. However, we
+/// should be able to spend nearly this amount.
 #[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;
@@ -484,6 +520,10 @@ pub extern "C" fn ChannelDetails_get_outbound_capacity_msat(this_ptr: &ChannelDe
 /// 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.
+///
+/// This value is not exact. Due to various in-flight changes, feerate changes, and our
+/// conflict-avoidance policy, exactly this amount is not likely to be spendable. However, we
+/// should be able to spend nearly this amount.
 #[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;
@@ -493,6 +533,10 @@ pub extern "C" fn ChannelDetails_set_outbound_capacity_msat(this_ptr: &mut Chann
 /// 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.
+///
+/// This value is not exact. Due to various in-flight changes, feerate changes, and our
+/// counterparty's conflict-avoidance policy, exactly this amount is not likely to be spendable.
+/// However, our counterparty should be able to spend nearly this amount.
 #[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;
@@ -503,10 +547,72 @@ pub extern "C" fn ChannelDetails_get_inbound_capacity_msat(this_ptr: &ChannelDet
 /// 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.
+///
+/// This value is not exact. Due to various in-flight changes, feerate changes, and our
+/// counterparty's conflict-avoidance policy, exactly this amount is not likely to be spendable.
+/// However, our counterparty should be able to spend nearly this amount.
 #[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;
 }
+/// The number of required confirmations on the funding transaction before the funding will be
+/// considered \"locked\". This number is selected by the channel fundee (i.e. us if
+/// [`is_outbound`] is *not* set), and can be selected for inbound channels with
+/// [`ChannelHandshakeConfig::minimum_depth`] or limited for outbound channels with
+/// [`ChannelHandshakeLimits::max_minimum_depth`].
+///
+/// This value will be `None` for outbound channels until the counterparty accepts the channel.
+///
+/// [`is_outbound`]: ChannelDetails::is_outbound
+/// [`ChannelHandshakeConfig::minimum_depth`]: crate::util::config::ChannelHandshakeConfig::minimum_depth
+/// [`ChannelHandshakeLimits::max_minimum_depth`]: crate::util::config::ChannelHandshakeLimits::max_minimum_depth
+#[no_mangle]
+pub extern "C" fn ChannelDetails_get_confirmations_required(this_ptr: &ChannelDetails) -> crate::c_types::derived::COption_u32Z {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.confirmations_required;
+       let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_u32Z::None } else {  { crate::c_types::derived::COption_u32Z::Some(inner_val.unwrap()) } };
+       local_inner_val
+}
+/// The number of required confirmations on the funding transaction before the funding will be
+/// considered \"locked\". This number is selected by the channel fundee (i.e. us if
+/// [`is_outbound`] is *not* set), and can be selected for inbound channels with
+/// [`ChannelHandshakeConfig::minimum_depth`] or limited for outbound channels with
+/// [`ChannelHandshakeLimits::max_minimum_depth`].
+///
+/// This value will be `None` for outbound channels until the counterparty accepts the channel.
+///
+/// [`is_outbound`]: ChannelDetails::is_outbound
+/// [`ChannelHandshakeConfig::minimum_depth`]: crate::util::config::ChannelHandshakeConfig::minimum_depth
+/// [`ChannelHandshakeLimits::max_minimum_depth`]: crate::util::config::ChannelHandshakeLimits::max_minimum_depth
+#[no_mangle]
+pub extern "C" fn ChannelDetails_set_confirmations_required(this_ptr: &mut ChannelDetails, mut val: crate::c_types::derived::COption_u32Z) {
+       let mut local_val = if val.is_some() { Some( { val.take() }) } else { None };
+       unsafe { &mut *this_ptr.inner }.confirmations_required = local_val;
+}
+/// The number of blocks (after our commitment transaction confirms) that we will need to wait
+/// until we can claim our funds after we force-close the channel. During this time our
+/// counterparty is allowed to punish us if we broadcasted a stale state. If our counterparty
+/// force-closes the channel and broadcasts a commitment transaction we do not have to wait any
+/// time to claim our non-HTLC-encumbered funds.
+///
+/// This value will be `None` for outbound channels until the counterparty accepts the channel.
+#[no_mangle]
+pub extern "C" fn ChannelDetails_get_force_close_spend_delay(this_ptr: &ChannelDetails) -> crate::c_types::derived::COption_u16Z {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.force_close_spend_delay;
+       let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_u16Z::None } else {  { crate::c_types::derived::COption_u16Z::Some(inner_val.unwrap()) } };
+       local_inner_val
+}
+/// The number of blocks (after our commitment transaction confirms) that we will need to wait
+/// until we can claim our funds after we force-close the channel. During this time our
+/// counterparty is allowed to punish us if we broadcasted a stale state. If our counterparty
+/// force-closes the channel and broadcasts a commitment transaction we do not have to wait any
+/// time to claim our non-HTLC-encumbered funds.
+///
+/// This value will be `None` for outbound channels until the counterparty accepts the channel.
+#[no_mangle]
+pub extern "C" fn ChannelDetails_set_force_close_spend_delay(this_ptr: &mut ChannelDetails, mut val: crate::c_types::derived::COption_u16Z) {
+       let mut local_val = if val.is_some() { Some( { val.take() }) } else { None };
+       unsafe { &mut *this_ptr.inner }.force_close_spend_delay = local_val;
+}
 /// True if the channel was initiated (and thus funded) by us.
 #[no_mangle]
 pub extern "C" fn ChannelDetails_get_is_outbound(this_ptr: &ChannelDetails) -> bool {
@@ -521,7 +627,10 @@ pub extern "C" fn ChannelDetails_set_is_outbound(this_ptr: &mut ChannelDetails,
 /// True if the channel is confirmed, funding_locked messages have been exchanged, and the
 /// channel is not currently being shut down. `funding_locked` message exchange implies the
 /// required confirmation count has been reached (and we were connected to the peer at some
-/// point after the funding transaction received enough confirmations).
+/// point after the funding transaction received enough confirmations). The required
+/// confirmation count is provided in [`confirmations_required`].
+///
+/// [`confirmations_required`]: ChannelDetails::confirmations_required
 #[no_mangle]
 pub extern "C" fn ChannelDetails_get_is_funding_locked(this_ptr: &ChannelDetails) -> bool {
        let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_funding_locked;
@@ -530,14 +639,16 @@ pub extern "C" fn ChannelDetails_get_is_funding_locked(this_ptr: &ChannelDetails
 /// True if the channel is confirmed, funding_locked messages have been exchanged, and the
 /// channel is not currently being shut down. `funding_locked` message exchange implies the
 /// required confirmation count has been reached (and we were connected to the peer at some
-/// point after the funding transaction received enough confirmations).
+/// point after the funding transaction received enough confirmations). The required
+/// confirmation count is provided in [`confirmations_required`].
+///
+/// [`confirmations_required`]: ChannelDetails::confirmations_required
 #[no_mangle]
 pub extern "C" fn ChannelDetails_set_is_funding_locked(this_ptr: &mut ChannelDetails, mut val: bool) {
        unsafe { &mut *this_ptr.inner }.is_funding_locked = val;
 }
 /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
-/// the peer is connected, (c) no monitor update failure is pending resolution, and (d) the
-/// channel is not currently negotiating a shutdown.
+/// the peer is connected, and (c) the channel is not currently negotiating a shutdown.
 ///
 /// This is a strict superset of `is_funding_locked`.
 #[no_mangle]
@@ -546,8 +657,7 @@ pub extern "C" fn ChannelDetails_get_is_usable(this_ptr: &ChannelDetails) -> boo
        *inner_val
 }
 /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
-/// the peer is connected, (c) no monitor update failure is pending resolution, and (d) the
-/// channel is not currently negotiating a shutdown.
+/// the peer is connected, and (c) the channel is not currently negotiating a shutdown.
 ///
 /// This is a strict superset of `is_funding_locked`.
 #[no_mangle]
@@ -565,6 +675,33 @@ pub extern "C" fn ChannelDetails_get_is_public(this_ptr: &ChannelDetails) -> boo
 pub extern "C" fn ChannelDetails_set_is_public(this_ptr: &mut ChannelDetails, mut val: bool) {
        unsafe { &mut *this_ptr.inner }.is_public = val;
 }
+/// Constructs a new ChannelDetails given each field
+#[must_use]
+#[no_mangle]
+pub extern "C" fn ChannelDetails_new(mut channel_id_arg: crate::c_types::ThirtyTwoBytes, mut counterparty_arg: crate::lightning::ln::channelmanager::ChannelCounterparty, mut funding_txo_arg: crate::lightning::chain::transaction::OutPoint, mut short_channel_id_arg: crate::c_types::derived::COption_u64Z, mut channel_value_satoshis_arg: u64, mut unspendable_punishment_reserve_arg: crate::c_types::derived::COption_u64Z, mut user_id_arg: u64, mut outbound_capacity_msat_arg: u64, mut inbound_capacity_msat_arg: u64, mut confirmations_required_arg: crate::c_types::derived::COption_u32Z, mut force_close_spend_delay_arg: crate::c_types::derived::COption_u16Z, mut is_outbound_arg: bool, mut is_funding_locked_arg: bool, mut is_usable_arg: bool, mut is_public_arg: bool) -> ChannelDetails {
+       let mut local_funding_txo_arg = if funding_txo_arg.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(funding_txo_arg.take_inner()) } }) };
+       let mut local_short_channel_id_arg = if short_channel_id_arg.is_some() { Some( { short_channel_id_arg.take() }) } else { None };
+       let mut local_unspendable_punishment_reserve_arg = if unspendable_punishment_reserve_arg.is_some() { Some( { unspendable_punishment_reserve_arg.take() }) } else { None };
+       let mut local_confirmations_required_arg = if confirmations_required_arg.is_some() { Some( { confirmations_required_arg.take() }) } else { None };
+       let mut local_force_close_spend_delay_arg = if force_close_spend_delay_arg.is_some() { Some( { force_close_spend_delay_arg.take() }) } else { None };
+       ChannelDetails { inner: Box::into_raw(Box::new(nativeChannelDetails {
+               channel_id: channel_id_arg.data,
+               counterparty: *unsafe { Box::from_raw(counterparty_arg.take_inner()) },
+               funding_txo: local_funding_txo_arg,
+               short_channel_id: local_short_channel_id_arg,
+               channel_value_satoshis: channel_value_satoshis_arg,
+               unspendable_punishment_reserve: local_unspendable_punishment_reserve_arg,
+               user_id: user_id_arg,
+               outbound_capacity_msat: outbound_capacity_msat_arg,
+               inbound_capacity_msat: inbound_capacity_msat_arg,
+               confirmations_required: local_confirmations_required_arg,
+               force_close_spend_delay: local_force_close_spend_delay_arg,
+               is_outbound: is_outbound_arg,
+               is_funding_locked: is_funding_locked_arg,
+               is_usable: is_usable_arg,
+               is_public: is_public_arg,
+       })), is_owned: true }
+}
 impl Clone for ChannelDetails {
        fn clone(&self) -> Self {
                Self {
@@ -792,6 +929,10 @@ pub extern "C" fn ChannelManager_get_current_default_configuration(this_arg: &Ch
 ///
 /// 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.
+///
+/// Note that we do not check if you are currently connected to the given peer. If no
+/// connection is available, the outbound `open_channel` message may fail to send, resulting in
+/// the channel eventually being silently forgotten.
 #[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::lightning::util::config::UserConfig) -> crate::c_types::derived::CResult_NoneAPIErrorZ {
@@ -1263,6 +1404,15 @@ pub extern "C" fn ChannelManager_await_persistable_update(this_arg: &ChannelMana
        unsafe { &*this_arg.inner }.await_persistable_update()
 }
 
+/// Gets the latest best block which was connected either via the [`chain::Listen`] or
+/// [`chain::Confirm`] interfaces.
+#[must_use]
+#[no_mangle]
+pub extern "C" fn ChannelManager_current_best_block(this_arg: &ChannelManager) -> crate::lightning::chain::BestBlock {
+       let mut ret = unsafe { &*this_arg.inner }.current_best_block();
+       crate::lightning::chain::BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true }
+}
+
 impl From<nativeChannelManager> for crate::lightning::ln::msgs::ChannelMessageHandler {
        fn from(obj: nativeChannelManager) -> Self {
                let mut rust_obj = ChannelManager { inner: Box::into_raw(Box::new(obj)), is_owned: true };
index 4bf1f4d57e7579097bd3bd0d7184d38cda382ee2..034f30763f889973232a585a93c5ee97db52dacc 100644 (file)
@@ -4014,6 +4014,9 @@ pub enum ErrorAction {
        },
        /// The peer did something harmless that we weren't able to process, just log and ignore
        IgnoreError,
+       /// The peer did something harmless that we weren't able to meaningfully process.
+       /// If the error is logged, log it at the given level.
+       IgnoreAndLog(crate::lightning::util::logger::Level),
        /// The peer did something incorrect. Tell them.
        SendErrorMessage {
                /// The message to send.
@@ -4033,6 +4036,12 @@ impl ErrorAction {
                                }
                        },
                        ErrorAction::IgnoreError => nativeErrorAction::IgnoreError,
+                       ErrorAction::IgnoreAndLog (ref a, ) => {
+                               let mut a_nonref = (*a).clone();
+                               nativeErrorAction::IgnoreAndLog (
+                                       a_nonref.into_native(),
+                               )
+                       },
                        ErrorAction::SendErrorMessage {ref msg, } => {
                                let mut msg_nonref = (*msg).clone();
                                nativeErrorAction::SendErrorMessage {
@@ -4051,6 +4060,11 @@ impl ErrorAction {
                                }
                        },
                        ErrorAction::IgnoreError => nativeErrorAction::IgnoreError,
+                       ErrorAction::IgnoreAndLog (mut a, ) => {
+                               nativeErrorAction::IgnoreAndLog (
+                                       a.into_native(),
+                               )
+                       },
                        ErrorAction::SendErrorMessage {mut msg, } => {
                                nativeErrorAction::SendErrorMessage {
                                        msg: *unsafe { Box::from_raw(msg.take_inner()) },
@@ -4069,6 +4083,12 @@ impl ErrorAction {
                                }
                        },
                        nativeErrorAction::IgnoreError => ErrorAction::IgnoreError,
+                       nativeErrorAction::IgnoreAndLog (ref a, ) => {
+                               let mut a_nonref = (*a).clone();
+                               ErrorAction::IgnoreAndLog (
+                                       crate::lightning::util::logger::Level::native_into(a_nonref),
+                               )
+                       },
                        nativeErrorAction::SendErrorMessage {ref msg, } => {
                                let mut msg_nonref = (*msg).clone();
                                ErrorAction::SendErrorMessage {
@@ -4087,6 +4107,11 @@ impl ErrorAction {
                                }
                        },
                        nativeErrorAction::IgnoreError => ErrorAction::IgnoreError,
+                       nativeErrorAction::IgnoreAndLog (mut a, ) => {
+                               ErrorAction::IgnoreAndLog (
+                                       crate::lightning::util::logger::Level::native_into(a),
+                               )
+                       },
                        nativeErrorAction::SendErrorMessage {mut msg, } => {
                                ErrorAction::SendErrorMessage {
                                        msg: crate::lightning::ln::msgs::ErrorMessage { inner: Box::into_raw(Box::new(msg)), is_owned: true },
index 413c144246fc291981b9297cb286a819357e713b..c9d1e4835f9e1d68b864cc14e14830c2980a288d 100644 (file)
@@ -432,27 +432,37 @@ impl MessageHandler {
        }
 }
 /// A message handler which handles messages specific to channels. Usually this is just a
-/// ChannelManager object or a ErroringMessageHandler.
+/// [`ChannelManager`] object or an [`ErroringMessageHandler`].
+///
+/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
 #[no_mangle]
 pub extern "C" fn MessageHandler_get_chan_handler(this_ptr: &MessageHandler) -> *const crate::lightning::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 or a ErroringMessageHandler.
+/// [`ChannelManager`] object or an [`ErroringMessageHandler`].
+///
+/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
 #[no_mangle]
 pub extern "C" fn MessageHandler_set_chan_handler(this_ptr: &mut MessageHandler, mut val: crate::lightning::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 or an IgnoringMessageHandler.
+/// graph. Usually this is just a [`NetGraphMsgHandler`] object or an
+/// [`IgnoringMessageHandler`].
+///
+/// [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler
 #[no_mangle]
 pub extern "C" fn MessageHandler_get_route_handler(this_ptr: &MessageHandler) -> *const crate::lightning::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 or an IgnoringMessageHandler.
+/// graph. Usually this is just a [`NetGraphMsgHandler`] object or an
+/// [`IgnoringMessageHandler`].
+///
+/// [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler
 #[no_mangle]
 pub extern "C" fn MessageHandler_set_route_handler(this_ptr: &mut MessageHandler, mut val: crate::lightning::ln::msgs::RoutingMessageHandler) {
        unsafe { &mut *this_ptr.inner }.route_handler = val;
@@ -472,11 +482,12 @@ pub extern "C" fn MessageHandler_new(mut chan_handler_arg: crate::lightning::ln:
 ///
 /// 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().
+/// Two descriptors may compare equal (by [`cmp::Eq`] and [`hash::Hash`]) as long as the original
+/// has been disconnected, the [`PeerManager`] has been informed of the disconnection (either by it
+/// having triggered the disconnection or a call to [`PeerManager::socket_disconnected`]), and no
+/// further calls to the [`PeerManager`] related to the original socket occur. This allows you to
+/// use a file descriptor for your SocketDescriptor directly, however for simplicity you may wish
+/// to simply use another value which is guaranteed to be globally unique instead.
 #[repr(C)]
 pub struct SocketDescriptor {
        /// An opaque pointer which is passed to your function implementations as an argument.
@@ -485,24 +496,26 @@ pub struct SocketDescriptor {
        /// 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.
+       /// Note that in the disconnected case, [`PeerManager::socket_disconnected`] must still be
+       /// called 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 the returned size is smaller than `data.len()`, a
+       /// [`PeerManager::write_buffer_space_avail`] call must be made the next time more data can be
+       /// written. Additionally, until a `send_data` event completes fully, no further
+       /// [`PeerManager::read_event`] calls should be made for the same peer! Because this is to
+       /// prevent denial-of-service issues, you should not read or buffer any data from the socket
+       /// until then.
        ///
-       /// 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.
+       /// If a [`PeerManager::read_event`] call 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 carries no meaning, and should not cause any action.
        #[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.
+       /// Disconnect the socket pointed to by this SocketDescriptor.
+       ///
+       /// You do *not* need to call [`PeerManager::socket_disconnected`] with this socket after this
+       /// call (doing so is a noop).
        pub disconnect_socket: extern "C" fn (this_arg: *mut c_void),
        /// Checks if two objects are equal given this object's this_arg pointer and another object.
        pub eq: extern "C" fn (this_arg: *const c_void, other_arg: &SocketDescriptor) -> bool,
@@ -666,14 +679,25 @@ pub extern "C" fn PeerHandleError_clone(orig: &PeerHandleError) -> PeerHandleErr
 use lightning::ln::peer_handler::PeerManager as nativePeerManagerImport;
 type nativePeerManager = nativePeerManagerImport<crate::lightning::ln::peer_handler::SocketDescriptor, crate::lightning::ln::msgs::ChannelMessageHandler, crate::lightning::ln::msgs::RoutingMessageHandler, crate::lightning::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.
+/// A PeerManager manages a set of peers, described by their [`SocketDescriptor`] and marshalls
+/// socket events into messages which it passes on to its [`MessageHandler`].
+///
+/// Locks are taken internally, so you must never assume that reentrancy from a
+/// [`SocketDescriptor`] call back into [`PeerManager`] methods will not deadlock.
+///
+/// Calls to [`read_event`] will decode relevant messages and pass them to the
+/// [`ChannelMessageHandler`], likely doing message processing in-line. Thus, the primary form of
+/// parallelism in Rust-Lightning is in calls to [`read_event`]. Note, however, that calls to any
+/// [`PeerManager`] functions related to the same connection must occur only in serial, making new
+/// calls only after previous ones have returned.
 ///
 /// 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.
+///
+/// [`read_event`]: PeerManager::read_event
 #[must_use]
 #[repr(C)]
 pub struct PeerManager {
@@ -743,8 +767,10 @@ pub extern "C" fn PeerManager_get_peer_node_ids(this_arg: &PeerManager) -> crate
 ///
 /// 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().
+/// Panics if descriptor is duplicative with some other descriptor which has not yet been
+/// [`socket_disconnected()`].
+///
+/// [`socket_disconnected()`]: PeerManager::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::lightning::ln::peer_handler::SocketDescriptor) -> crate::c_types::derived::CResult_CVec_u8ZPeerHandleErrorZ {
@@ -760,8 +786,10 @@ pub extern "C" fn PeerManager_new_outbound_connection(this_arg: &PeerManager, mu
 /// 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.
+/// Panics if descriptor is duplicative with some other descriptor which has not yet been
+/// [`socket_disconnected()`].
+///
+/// [`socket_disconnected()`]: PeerManager::socket_disconnected
 #[must_use]
 #[no_mangle]
 pub extern "C" fn PeerManager_new_inbound_connection(this_arg: &PeerManager, mut descriptor: crate::lightning::ln::peer_handler::SocketDescriptor) -> crate::c_types::derived::CResult_NonePeerHandleErrorZ {
@@ -774,12 +802,14 @@ pub extern "C" fn PeerManager_new_inbound_connection(this_arg: &PeerManager, mut
 ///
 /// 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.
+/// May call [`send_data`] on the descriptor passed in (or an equal descriptor) 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!
+///
+/// [`send_data`]: SocketDescriptor::send_data
+/// [`write_buffer_space_avail`]: PeerManager::write_buffer_space_avail
 #[must_use]
 #[no_mangle]
 pub extern "C" fn PeerManager_write_buffer_space_avail(this_arg: &PeerManager, descriptor: &mut crate::lightning::ln::peer_handler::SocketDescriptor) -> crate::c_types::derived::CResult_NonePeerHandleErrorZ {
@@ -792,14 +822,16 @@ pub extern "C" fn PeerManager_write_buffer_space_avail(this_arg: &PeerManager, d
 ///
 /// 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.
+/// Will *not* call back into [`send_data`] on any descriptors to avoid reentrancy complexity.
+/// Thus, however, you should 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).
+/// If `Ok(true)` is returned, further read_events should not be triggered until a
+/// [`send_data`] call on this 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.
+/// [`send_data`]: SocketDescriptor::send_data
+/// [`process_events`]: PeerManager::process_events
 #[must_use]
 #[no_mangle]
 pub extern "C" fn PeerManager_read_event(this_arg: &PeerManager, peer_descriptor: &mut crate::lightning::ln::peer_handler::SocketDescriptor, mut data: crate::c_types::u8slice) -> crate::c_types::derived::CResult_boolPeerHandleErrorZ {
@@ -810,20 +842,20 @@ pub extern "C" fn PeerManager_read_event(this_arg: &PeerManager, peer_descriptor
 
 /// 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).
+/// functions like [`ChannelManager::process_pending_htlc_forwards`] or [`send_payment`]).
+///
+/// May call [`send_data`] on [`SocketDescriptor`]s. Thus, be very careful with reentrancy
+/// issues!
+///
+/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
+/// [`ChannelManager::process_pending_htlc_forwards`]: crate::ln::channelmanager::ChannelManager::process_pending_htlc_forwards
+/// [`send_data`]: SocketDescriptor::send_data
 #[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::lightning::ln::peer_handler::SocketDescriptor) {
        unsafe { &*this_arg.inner }.socket_disconnected(descriptor)
@@ -831,19 +863,26 @@ pub extern "C" fn PeerManager_socket_disconnected(this_arg: &PeerManager, descri
 
 /// Disconnect a peer given its node id.
 ///
-/// Set no_connection_possible to true to prevent any further connection with this peer,
+/// Set `no_connection_possible` to true to prevent any further connection with this peer,
 /// force-closing any channels we have with it.
 ///
-/// If a peer is connected, this will call `disconnect_socket` on the descriptor for the peer,
-/// so be careful about reentrancy issues.
+/// If a peer is connected, this will call [`disconnect_socket`] on the descriptor for the
+/// peer. Thus, be very careful about reentrancy issues.
+///
+/// [`disconnect_socket`]: SocketDescriptor::disconnect_socket
 #[no_mangle]
 pub extern "C" fn PeerManager_disconnect_by_node_id(this_arg: &PeerManager, mut node_id: crate::c_types::PublicKey, mut no_connection_possible: bool) {
        unsafe { &*this_arg.inner }.disconnect_by_node_id(node_id.into_rust(), no_connection_possible)
 }
 
 /// 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!
+/// It will send pings to each peer and disconnect those which did not respond to the last
+/// round of pings.
+///
+/// May call [`send_data`] on all [`SocketDescriptor`]s. Thus, be very careful with reentrancy
+/// issues!
+///
+/// [`send_data`]: SocketDescriptor::send_data
 #[no_mangle]
 pub extern "C" fn PeerManager_timer_tick_occurred(this_arg: &PeerManager) {
        unsafe { &*this_arg.inner }.timer_tick_occurred()
index 63def438b9558bf52c754d844c98985bd4b9c245..28acdcafac84587df5e20d505e0bd777cac74109 100644 (file)
@@ -340,21 +340,27 @@ pub extern "C" fn ChannelHandshakeLimits_get_max_minimum_depth(this_ptr: &Channe
 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.
+/// Set to force an incoming channel to match our announced channel preference in
+/// [`ChannelConfig::announced_channel`].
 ///
-/// 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).
+/// For a node which is not online reliably, this should be set to true and
+/// [`ChannelConfig::announced_channel`] set to false, ensuring that no announced (aka public)
+/// channels will ever be opened.
+///
+/// Default value: true.
 #[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.
+/// Set to force an incoming channel to match our announced channel preference in
+/// [`ChannelConfig::announced_channel`].
 ///
-/// 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).
+/// For a node which is not online reliably, this should be set to true and
+/// [`ChannelConfig::announced_channel`] set to false, ensuring that no announced (aka public)
+/// channels will ever be opened.
+///
+/// Default value: true.
 #[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;
@@ -468,24 +474,59 @@ impl ChannelConfig {
                ret
        }
 }
-/// Amount (in millionths of a satoshi) the channel will charge per transferred satoshi.
+/// Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound
+/// over the channel.
 /// 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;
+pub extern "C" fn ChannelConfig_get_forwarding_fee_proportional_millionths(this_ptr: &ChannelConfig) -> u32 {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.forwarding_fee_proportional_millionths;
        *inner_val
 }
-/// Amount (in millionths of a satoshi) the channel will charge per transferred satoshi.
+/// Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound
+/// over the channel.
 /// 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;
+pub extern "C" fn ChannelConfig_set_forwarding_fee_proportional_millionths(this_ptr: &mut ChannelConfig, mut val: u32) {
+       unsafe { &mut *this_ptr.inner }.forwarding_fee_proportional_millionths = val;
+}
+/// Amount (in milli-satoshi) charged for payments forwarded outbound over the channel, in
+/// excess of [`forwarding_fee_proportional_millionths`].
+/// 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.
+///
+/// The default value of a single satoshi roughly matches the market rate on many routing nodes
+/// as of July 2021. Adjusting it upwards or downwards may change whether nodes route through
+/// this node.
+///
+/// Default value: 1000.
+///
+/// [`forwarding_fee_proportional_millionths`]: ChannelConfig::forwarding_fee_proportional_millionths
+#[no_mangle]
+pub extern "C" fn ChannelConfig_get_forwarding_fee_base_msat(this_ptr: &ChannelConfig) -> u32 {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.forwarding_fee_base_msat;
+       *inner_val
+}
+/// Amount (in milli-satoshi) charged for payments forwarded outbound over the channel, in
+/// excess of [`forwarding_fee_proportional_millionths`].
+/// 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.
+///
+/// The default value of a single satoshi roughly matches the market rate on many routing nodes
+/// as of July 2021. Adjusting it upwards or downwards may change whether nodes route through
+/// this node.
+///
+/// Default value: 1000.
+///
+/// [`forwarding_fee_proportional_millionths`]: ChannelConfig::forwarding_fee_proportional_millionths
+#[no_mangle]
+pub extern "C" fn ChannelConfig_set_forwarding_fee_base_msat(this_ptr: &mut ChannelConfig, mut val: u32) {
+       unsafe { &mut *this_ptr.inner }.forwarding_fee_base_msat = val;
 }
 /// The difference in the CLTV value between incoming HTLCs and an outbound HTLC forwarded over
 /// the channel this config applies to.
@@ -540,7 +581,7 @@ pub extern "C" fn ChannelConfig_set_cltv_expiry_delta(this_ptr: &mut ChannelConf
 /// 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.
+/// channels unless [`ChannelHandshakeLimits::force_announced_channel_preference`] is set.
 ///
 /// This cannot be changed after the initial channel handshake.
 ///
@@ -556,7 +597,7 @@ pub extern "C" fn ChannelConfig_get_announced_channel(this_ptr: &ChannelConfig)
 /// 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.
+/// channels unless [`ChannelHandshakeLimits::force_announced_channel_preference`] is set.
 ///
 /// This cannot be changed after the initial channel handshake.
 ///
@@ -599,9 +640,10 @@ pub extern "C" fn ChannelConfig_set_commit_upfront_shutdown_pubkey(this_ptr: &mu
 /// Constructs a new ChannelConfig given each field
 #[must_use]
 #[no_mangle]
-pub extern "C" fn ChannelConfig_new(mut fee_proportional_millionths_arg: u32, mut cltv_expiry_delta_arg: u16, mut announced_channel_arg: bool, mut commit_upfront_shutdown_pubkey_arg: bool) -> ChannelConfig {
+pub extern "C" fn ChannelConfig_new(mut forwarding_fee_proportional_millionths_arg: u32, mut forwarding_fee_base_msat_arg: u32, mut cltv_expiry_delta_arg: u16, 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,
+               forwarding_fee_proportional_millionths: forwarding_fee_proportional_millionths_arg,
+               forwarding_fee_base_msat: forwarding_fee_base_msat_arg,
                cltv_expiry_delta: cltv_expiry_delta_arg,
                announced_channel: announced_channel_arg,
                commit_upfront_shutdown_pubkey: commit_upfront_shutdown_pubkey_arg,
@@ -729,14 +771,56 @@ pub extern "C" fn UserConfig_get_channel_options(this_ptr: &UserConfig) -> crate
 pub extern "C" fn UserConfig_set_channel_options(this_ptr: &mut UserConfig, mut val: crate::lightning::util::config::ChannelConfig) {
        unsafe { &mut *this_ptr.inner }.channel_options = *unsafe { Box::from_raw(val.take_inner()) };
 }
+/// If this is set to false, we will reject any HTLCs which were to be forwarded over private
+/// channels. This prevents us from taking on HTLC-forwarding risk when we intend to run as a
+/// node which is not online reliably.
+///
+/// For nodes which are not online reliably, you should set all channels to *not* be announced
+/// (using [`ChannelConfig::announced_channel`] and
+/// [`ChannelHandshakeLimits::force_announced_channel_preference`]) and set this to false to
+/// ensure you are not exposed to any forwarding risk.
+///
+/// Note that because you cannot change a channel's announced state after creation, there is no
+/// way to disable forwarding on public channels retroactively. Thus, in order to change a node
+/// from a publicly-announced forwarding node to a private non-forwarding node you must close
+/// all your channels and open new ones. For privacy, you should also change your node_id
+/// (swapping all private and public key material for new ones) at that time.
+///
+/// Default value: false.
+#[no_mangle]
+pub extern "C" fn UserConfig_get_accept_forwards_to_priv_channels(this_ptr: &UserConfig) -> bool {
+       let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.accept_forwards_to_priv_channels;
+       *inner_val
+}
+/// If this is set to false, we will reject any HTLCs which were to be forwarded over private
+/// channels. This prevents us from taking on HTLC-forwarding risk when we intend to run as a
+/// node which is not online reliably.
+///
+/// For nodes which are not online reliably, you should set all channels to *not* be announced
+/// (using [`ChannelConfig::announced_channel`] and
+/// [`ChannelHandshakeLimits::force_announced_channel_preference`]) and set this to false to
+/// ensure you are not exposed to any forwarding risk.
+///
+/// Note that because you cannot change a channel's announced state after creation, there is no
+/// way to disable forwarding on public channels retroactively. Thus, in order to change a node
+/// from a publicly-announced forwarding node to a private non-forwarding node you must close
+/// all your channels and open new ones. For privacy, you should also change your node_id
+/// (swapping all private and public key material for new ones) at that time.
+///
+/// Default value: false.
+#[no_mangle]
+pub extern "C" fn UserConfig_set_accept_forwards_to_priv_channels(this_ptr: &mut UserConfig, mut val: bool) {
+       unsafe { &mut *this_ptr.inner }.accept_forwards_to_priv_channels = val;
+}
 /// Constructs a new UserConfig given each field
 #[must_use]
 #[no_mangle]
-pub extern "C" fn UserConfig_new(mut own_channel_config_arg: crate::lightning::util::config::ChannelHandshakeConfig, mut peer_channel_config_limits_arg: crate::lightning::util::config::ChannelHandshakeLimits, mut channel_options_arg: crate::lightning::util::config::ChannelConfig) -> UserConfig {
+pub extern "C" fn UserConfig_new(mut own_channel_config_arg: crate::lightning::util::config::ChannelHandshakeConfig, mut peer_channel_config_limits_arg: crate::lightning::util::config::ChannelHandshakeLimits, mut channel_options_arg: crate::lightning::util::config::ChannelConfig, mut accept_forwards_to_priv_channels_arg: bool) -> UserConfig {
        UserConfig { inner: Box::into_raw(Box::new(nativeUserConfig {
                own_channel_config: *unsafe { Box::from_raw(own_channel_config_arg.take_inner()) },
                peer_channel_config_limits: *unsafe { Box::from_raw(peer_channel_config_limits_arg.take_inner()) },
                channel_options: *unsafe { Box::from_raw(channel_options_arg.take_inner()) },
+               accept_forwards_to_priv_channels: accept_forwards_to_priv_channels_arg,
        })), is_owned: true }
 }
 impl Clone for UserConfig {
index cb28df82f252669b840434264f4e502570c29aae..7961f623bbc456c5ab50b8398cc3ddd0feca46fa 100644 (file)
@@ -460,6 +460,15 @@ pub enum MessageSendEvent {
                /// The channel_update which should be sent.
                msg: crate::lightning::ln::msgs::ChannelUpdate,
        },
+       /// Used to indicate that a channel_update should be sent to a single peer.
+       /// In contrast to [`Self::BroadcastChannelUpdate`], this is used when the channel is a
+       /// private channel and we shouldn't be informing all of our peers of channel parameters.
+       SendChannelUpdate {
+               /// The node_id of the node which should receive this message
+               node_id: crate::c_types::PublicKey,
+               /// The channel_update which should be sent.
+               msg: crate::lightning::ln::msgs::ChannelUpdate,
+       },
        /// Broadcast an error downstream to be handled
        HandleError {
                /// The node_id of the node which should receive this message
@@ -610,6 +619,14 @@ impl MessageSendEvent {
                                        msg: *unsafe { Box::from_raw(msg_nonref.take_inner()) },
                                }
                        },
+                       MessageSendEvent::SendChannelUpdate {ref node_id, ref msg, } => {
+                               let mut node_id_nonref = (*node_id).clone();
+                               let mut msg_nonref = (*msg).clone();
+                               nativeMessageSendEvent::SendChannelUpdate {
+                                       node_id: node_id_nonref.into_rust(),
+                                       msg: *unsafe { Box::from_raw(msg_nonref.take_inner()) },
+                               }
+                       },
                        MessageSendEvent::HandleError {ref node_id, ref action, } => {
                                let mut node_id_nonref = (*node_id).clone();
                                let mut action_nonref = (*action).clone();
@@ -735,6 +752,12 @@ impl MessageSendEvent {
                                        msg: *unsafe { Box::from_raw(msg.take_inner()) },
                                }
                        },
+                       MessageSendEvent::SendChannelUpdate {mut node_id, mut msg, } => {
+                               nativeMessageSendEvent::SendChannelUpdate {
+                                       node_id: node_id.into_rust(),
+                                       msg: *unsafe { Box::from_raw(msg.take_inner()) },
+                               }
+                       },
                        MessageSendEvent::HandleError {mut node_id, mut action, } => {
                                nativeMessageSendEvent::HandleError {
                                        node_id: node_id.into_rust(),
@@ -877,6 +900,14 @@ impl MessageSendEvent {
                                        msg: crate::lightning::ln::msgs::ChannelUpdate { inner: Box::into_raw(Box::new(msg_nonref)), is_owned: true },
                                }
                        },
+                       nativeMessageSendEvent::SendChannelUpdate {ref node_id, ref msg, } => {
+                               let mut node_id_nonref = (*node_id).clone();
+                               let mut msg_nonref = (*msg).clone();
+                               MessageSendEvent::SendChannelUpdate {
+                                       node_id: crate::c_types::PublicKey::from_rust(&node_id_nonref),
+                                       msg: crate::lightning::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();
@@ -1002,6 +1033,12 @@ impl MessageSendEvent {
                                        msg: crate::lightning::ln::msgs::ChannelUpdate { inner: Box::into_raw(Box::new(msg)), is_owned: true },
                                }
                        },
+                       nativeMessageSendEvent::SendChannelUpdate {mut node_id, mut msg, } => {
+                               MessageSendEvent::SendChannelUpdate {
+                                       node_id: crate::c_types::PublicKey::from_rust(&node_id),
+                                       msg: crate::lightning::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),
index 6a21fcbefcaa84d322fc5d8c2f7171ab4b3916cb..dc67386841c02ff3ba070e18694ed92dddadb497 100644 (file)
@@ -23,63 +23,57 @@ use crate::c_types::*;
 #[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,
+       /// Designates lower priority information
+       Debug,
+       /// Designates useful information
+       Info,
+       /// Designates hazardous situations
+       Warn,
+       /// Designates very serious errors
+       Error,
 }
 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,
+                       Level::Debug => nativeLevel::Debug,
+                       Level::Info => nativeLevel::Info,
+                       Level::Warn => nativeLevel::Warn,
+                       Level::Error => nativeLevel::Error,
                }
        }
        #[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,
+                       Level::Debug => nativeLevel::Debug,
+                       Level::Info => nativeLevel::Info,
+                       Level::Warn => nativeLevel::Warn,
+                       Level::Error => nativeLevel::Error,
                }
        }
        #[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,
+                       nativeLevel::Debug => Level::Debug,
+                       nativeLevel::Info => Level::Info,
+                       nativeLevel::Warn => Level::Warn,
+                       nativeLevel::Error => Level::Error,
                }
        }
        #[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,
+                       nativeLevel::Debug => Level::Debug,
+                       nativeLevel::Info => Level::Info,
+                       nativeLevel::Warn => Level::Warn,
+                       nativeLevel::Error => Level::Error,
                }
        }
 }
index 6aa95f59703d402086307b40cc939c840fb4b50a..b583dd42cdceda68f2eb13ebafb0884b46e9754b 100644 (file)
 //! Note this is not part of the specs, but follows lnd's signing and verifying protocol, which can is defined as follows:
 //!
 //! signature = zbase32(SigRec(sha256d((\"Lightning Signed Message:\" + msg)))
-//! zbase32 from https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
+//! zbase32 from <https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt>
 //! SigRec has first byte 31 + recovery id, followed by 64 byte sig.
 //!
 //! This implementation is compatible with both lnd's and c-lightning's
 //!
-//! https://lightning.readthedocs.io/lightning-signmessage.7.html
-//! https://api.lightning.community/#signmessage
+//! <https://lightning.readthedocs.io/lightning-signmessage.7.html>
+//! <https://api.lightning.community/#signmessage>
 
 use std::str::FromStr;
 use std::ffi::c_void;
@@ -31,8 +31,8 @@ use crate::c_types::*;
 /// A receiver knowing the PublicKey (e.g. the node's id) and the message can be sure that the signature was generated by the caller.
 /// Signatures are EC recoverable, meaning that given the message and the signature the PublicKey of the signer can be extracted.
 #[no_mangle]
-pub extern "C" fn sign(mut msg: crate::c_types::u8slice, mut sk: crate::c_types::SecretKey) -> crate::c_types::derived::CResult_StringErrorZ {
-       let mut ret = lightning::util::message_signing::sign(msg.to_slice(), sk.into_rust());
+pub extern "C" fn sign(mut msg: crate::c_types::u8slice, sk: *const [u8; 32]) -> crate::c_types::derived::CResult_StringErrorZ {
+       let mut ret = lightning::util::message_signing::sign(msg.to_slice(), &::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *sk}[..]).unwrap());
        let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { o.into() }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::c_types::Secp256k1Error::from_rust(e) }).into() };
        local_ret
 }
@@ -49,7 +49,7 @@ pub extern "C" fn recover_pk(mut msg: crate::c_types::u8slice, mut sig: crate::c
 /// and the PublicKey.
 #[no_mangle]
 pub extern "C" fn verify(mut msg: crate::c_types::u8slice, mut sig: crate::c_types::Str, mut pk: crate::c_types::PublicKey) -> bool {
-       let mut ret = lightning::util::message_signing::verify(msg.to_slice(), sig.into_str(), pk.into_rust());
+       let mut ret = lightning::util::message_signing::verify(msg.to_slice(), sig.into_str(), &pk.into_rust());
        ret
 }
 
index eaa9aabbbc9258bb3d3dbe204f679b6fa695ea52..0891447b5f733a274ab3387e7657ae7c8ba4e0ec 100644 (file)
@@ -110,6 +110,22 @@ use bitcoin::hashes::Hash;
 use crate::c_types::*;
 
 }
+/// Default expiry time as defined by [BOLT 11].
+///
+/// [BOLT 11]: https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md
+
+#[no_mangle]
+pub static DEFAULT_EXPIRY_TIME: u64 = lightning_invoice::DEFAULT_EXPIRY_TIME;
+/// Default minimum final CLTV expiry as defined by [BOLT 11].
+///
+/// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry, which is
+/// provided in [`MIN_FINAL_CLTV_EXPIRY`].
+///
+/// [BOLT 11]: https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md
+/// [`MIN_FINAL_CLTV_EXPIRY`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY
+
+#[no_mangle]
+pub static DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = lightning_invoice::DEFAULT_MIN_FINAL_CLTV_EXPIRY;
 /// **Call this function on startup to ensure that all assumptions about the platform are valid.**
 ///
 /// Unfortunately we have to make assumptions about the upper bounds of the `SystemTime` type on