X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-c-bindings%2Fsrc%2Flightning%2Fonion_message%2Fmessenger.rs;h=5db56296a9ff14bf8d0b6f40de3f756c073cd0f9;hb=0ac4dbdb8352c898100b34f0ef8ed9cebfea7786;hp=b3a696c586879dd808cb42d465df368ddcdca8e3;hpb=c96981baf087d5441d079508ae71d2e046167ebf;p=ldk-c-bindings diff --git a/lightning-c-bindings/src/lightning/onion_message/messenger.rs b/lightning-c-bindings/src/lightning/onion_message/messenger.rs index b3a696c..5db5629 100644 --- a/lightning-c-bindings/src/lightning/onion_message/messenger.rs +++ b/lightning-c-bindings/src/lightning/onion_message/messenger.rs @@ -6,10 +6,11 @@ // license as that which applies to the original source files from which this // source was automatically generated. -//! LDK sends, receives, and forwards onion messages via the [`OnionMessenger`]. See its docs for -//! more information. +//! LDK sends, receives, and forwards onion messages via this [`OnionMessenger`], which lives here, +//! as well as various types, traits, and utilities that it uses. use alloc::str::FromStr; +use alloc::string::String; use core::ffi::c_void; use core::convert::Infallible; use bitcoin::hashes::Hash; @@ -19,60 +20,116 @@ use alloc::{vec::Vec, boxed::Box}; use lightning::onion_message::messenger::OnionMessenger as nativeOnionMessengerImport; -pub(crate) type nativeOnionMessenger = nativeOnionMessengerImport; +pub(crate) type nativeOnionMessenger = nativeOnionMessengerImport; -/// A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be -/// used to retrieve invoices and fulfill invoice requests from [offers]. Currently, only sending -/// and receiving empty onion messages is supported. +/// A sender, receiver and forwarder of [`OnionMessage`]s. +/// +/// # Handling Messages +/// +/// `OnionMessenger` implements [`OnionMessageHandler`], making it responsible for either forwarding +/// messages to peers or delegating to the appropriate handler for the message type. Currently, the +/// available handlers are: +/// * [`OffersMessageHandler`], for responding to [`InvoiceRequest`]s and paying [`Bolt12Invoice`]s +/// * [`CustomOnionMessageHandler`], for handling user-defined message types +/// +/// # Sending Messages +/// +/// [`OnionMessage`]s are sent initially using [`OnionMessenger::send_onion_message`]. When handling +/// a message, the matched handler may return a response message which `OnionMessenger` will send +/// on its behalf. /// /// # Example /// /// ``` /// # extern crate bitcoin; /// # use bitcoin::hashes::_export::_core::time::Duration; -/// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; -/// # use lightning::chain::keysinterface::{InMemorySigner, KeysManager, KeysInterface}; -/// # use lightning::onion_message::messenger::{Destination, OnionMessenger}; -/// # use lightning::onion_message::blinded_route::BlindedRoute; +/// # use bitcoin::hashes::hex::FromHex; +/// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self}; +/// # use lightning::blinded_path::BlindedPath; +/// # use lightning::sign::{EntropySource, KeysManager}; +/// # use lightning::ln::peer_handler::IgnoringMessageHandler; +/// # use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath, OnionMessenger}; +/// # use lightning::onion_message::packet::OnionMessageContents; /// # use lightning::util::logger::{Logger, Record}; +/// # use lightning::util::ser::{Writeable, Writer}; +/// # use lightning::io; /// # use std::sync::Arc; -/// # struct FakeLogger {}; +/// # struct FakeLogger; /// # impl Logger for FakeLogger { -/// # fn log(&self, record: &Record) { unimplemented!() } +/// # fn log(&self, record: Record) { println!(\"{:?}\" , record); } +/// # } +/// # struct FakeMessageRouter {} +/// # impl MessageRouter for FakeMessageRouter { +/// # fn find_path(&self, sender: PublicKey, peers: Vec, destination: Destination) -> Result { +/// # let secp_ctx = Secp256k1::new(); +/// # let node_secret = SecretKey::from_slice(&>::from_hex(\"0101010101010101010101010101010101010101010101010101010101010101\").unwrap()[..]).unwrap(); +/// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret); +/// # let hop_node_id2 = hop_node_id1; +/// # Ok(OnionMessagePath { +/// # intermediate_nodes: vec![hop_node_id1, hop_node_id2], +/// # destination, +/// # first_node_addresses: None, +/// # }) +/// # } +/// # fn create_blinded_paths( +/// # &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1 +/// # ) -> Result, ()> { +/// # unreachable!() +/// # } /// # } /// # let seed = [42u8; 32]; /// # let time = Duration::from_secs(123456); /// # let keys_manager = KeysManager::new(&seed, time.as_secs(), time.subsec_nanos()); /// # let logger = Arc::new(FakeLogger {}); -/// # let node_secret = SecretKey::from_slice(&hex::decode(\"0101010101010101010101010101010101010101010101010101010101010101\").unwrap()[..]).unwrap(); +/// # let node_secret = SecretKey::from_slice(&>::from_hex(\"0101010101010101010101010101010101010101010101010101010101010101\").unwrap()[..]).unwrap(); /// # let secp_ctx = Secp256k1::new(); /// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret); -/// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, -/// hop_node_id1); +/// # let (hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1); /// # let destination_node_id = hop_node_id1; -/// # +/// # let message_router = Arc::new(FakeMessageRouter {}); +/// # let custom_message_handler = IgnoringMessageHandler {}; +/// # let offers_message_handler = IgnoringMessageHandler {}; /// // Create the onion messenger. This must use the same `keys_manager` as is passed to your /// // ChannelManager. -/// let onion_messenger = OnionMessenger::new(&keys_manager, logger); +/// let onion_messenger = OnionMessenger::new( +/// &keys_manager, &keys_manager, logger, message_router, &offers_message_handler, +/// &custom_message_handler +/// ); /// -/// // Send an empty onion message to a node id. -/// let intermediate_hops = [hop_node_id1, hop_node_id2]; +/// # #[derive(Debug, Clone)] +/// # struct YourCustomMessage {} +/// impl Writeable for YourCustomMessage { +/// \tfn write(&self, w: &mut W) -> Result<(), io::Error> { +/// \t\t# Ok(()) +/// \t\t// Write your custom onion message to `w` +/// \t} +/// } +/// impl OnionMessageContents for YourCustomMessage { +/// \tfn tlv_type(&self) -> u64 { +/// \t\t# let your_custom_message_type = 42; +/// \t\tyour_custom_message_type +/// \t} +/// } +/// // Send a custom onion message to a node id. +/// let destination = Destination::Node(destination_node_id); /// let reply_path = None; -/// onion_messenger.send_onion_message(&intermediate_hops, Destination::Node(destination_node_id), reply_path); +/// # let message = YourCustomMessage {}; +/// onion_messenger.send_onion_message(message, destination, reply_path); /// -/// // Create a blinded route to yourself, for someone to send an onion message to. +/// // Create a blinded path to yourself, for someone to send an onion message to. /// # let your_node_id = hop_node_id1; /// let hops = [hop_node_id3, hop_node_id4, your_node_id]; -/// let blinded_route = BlindedRoute::new(&hops, &keys_manager, &secp_ctx).unwrap(); +/// let blinded_path = BlindedPath::new_for_message(&hops, &keys_manager, &secp_ctx).unwrap(); /// -/// // Send an empty onion message to a blinded route. -/// # let intermediate_hops = [hop_node_id1, hop_node_id2]; +/// // Send a custom onion message to a blinded path. +/// let destination = Destination::BlindedPath(blinded_path); /// let reply_path = None; -/// onion_messenger.send_onion_message(&intermediate_hops, Destination::BlindedRoute(blinded_route), reply_path); +/// # let message = YourCustomMessage {}; +/// onion_messenger.send_onion_message(message, destination, reply_path); /// ``` /// -/// [offers]: -/// [`OnionMessenger`]: crate::onion_message::OnionMessenger +/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[must_use] #[repr(C)] pub struct OnionMessenger { @@ -101,7 +158,7 @@ pub extern "C" fn OnionMessenger_free(this_obj: OnionMessenger) { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method pub(crate) extern "C" fn OnionMessenger_free_void(this_ptr: *mut c_void) { - unsafe { let _ = Box::from_raw(this_ptr as *mut nativeOnionMessenger); } + let _ = unsafe { Box::from_raw(this_ptr as *mut nativeOnionMessenger) }; } #[allow(unused)] impl OnionMessenger { @@ -119,21 +176,338 @@ impl OnionMessenger { ret } } +/// A trait defining behavior for routing an [`OnionMessage`]. +#[repr(C)] +pub struct MessageRouter { + /// An opaque pointer which is passed to your function implementations as an argument. + /// This has no meaning in the LDK, and can be NULL or any other value. + pub this_arg: *mut c_void, + /// Returns a route for sending an [`OnionMessage`] to the given [`Destination`]. + pub find_path: extern "C" fn (this_arg: *const c_void, sender: crate::c_types::PublicKey, peers: crate::c_types::derived::CVec_PublicKeyZ, destination: crate::lightning::onion_message::messenger::Destination) -> crate::c_types::derived::CResult_OnionMessagePathNoneZ, + /// Creates [`BlindedPath`]s to the `recipient` node. The nodes in `peers` are assumed to be + /// direct peers with the `recipient`. + pub create_blinded_paths: extern "C" fn (this_arg: *const c_void, recipient: crate::c_types::PublicKey, peers: crate::c_types::derived::CVec_PublicKeyZ) -> crate::c_types::derived::CResult_CVec_BlindedPathZNoneZ, + /// Frees any resources associated with this object given its this_arg pointer. + /// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed. + pub free: Option, +} +unsafe impl Send for MessageRouter {} +unsafe impl Sync for MessageRouter {} +#[allow(unused)] +pub(crate) fn MessageRouter_clone_fields(orig: &MessageRouter) -> MessageRouter { + MessageRouter { + this_arg: orig.this_arg, + find_path: Clone::clone(&orig.find_path), + create_blinded_paths: Clone::clone(&orig.create_blinded_paths), + free: Clone::clone(&orig.free), + } +} + +use lightning::onion_message::messenger::MessageRouter as rustMessageRouter; +impl rustMessageRouter for MessageRouter { + fn find_path(&self, mut sender: bitcoin::secp256k1::PublicKey, mut peers: Vec, mut destination: lightning::onion_message::messenger::Destination) -> Result { + let mut local_peers = Vec::new(); for mut item in peers.drain(..) { local_peers.push( { crate::c_types::PublicKey::from_rust(&item) }); }; + let mut ret = (self.find_path)(self.this_arg, crate::c_types::PublicKey::from_rust(&sender), local_peers.into(), crate::lightning::onion_message::messenger::Destination::native_into(destination)); + let mut local_ret = match ret.result_ok { true => Ok( { *unsafe { Box::from_raw((*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).take_inner()) } }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })}; + local_ret + } + fn create_blinded_paths(&self, mut recipient: bitcoin::secp256k1::PublicKey, mut peers: Vec, mut _secp_ctx: &bitcoin::secp256k1::Secp256k1) -> Result, ()> { + let mut local_peers = Vec::new(); for mut item in peers.drain(..) { local_peers.push( { crate::c_types::PublicKey::from_rust(&item) }); }; + let mut ret = (self.create_blinded_paths)(self.this_arg, crate::c_types::PublicKey::from_rust(&recipient), local_peers.into()); + let mut local_ret = match ret.result_ok { true => Ok( { let mut local_ret_0 = Vec::new(); for mut item in (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }).into_rust().drain(..) { local_ret_0.push( { *unsafe { Box::from_raw(item.take_inner()) } }); }; local_ret_0 }), false => Err( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) })*/ })}; + local_ret + } +} + +// We're essentially a pointer already, or at least a set of pointers, so allow us to be used +// directly as a Deref trait in higher-level structs: +impl core::ops::Deref for MessageRouter { + type Target = Self; + fn deref(&self) -> &Self { + self + } +} +impl core::ops::DerefMut for MessageRouter { + fn deref_mut(&mut self) -> &mut Self { + self + } +} +/// Calls the free function if one is set +#[no_mangle] +pub extern "C" fn MessageRouter_free(this_ptr: MessageRouter) { } +impl Drop for MessageRouter { + fn drop(&mut self) { + if let Some(f) = self.free { + f(self.this_arg); + } + } +} + +use lightning::onion_message::messenger::DefaultMessageRouter as nativeDefaultMessageRouterImport; +pub(crate) type nativeDefaultMessageRouter = nativeDefaultMessageRouterImport<&'static lightning::routing::gossip::NetworkGraph, crate::lightning::util::logger::Logger, crate::lightning::sign::EntropySource>; + +/// A [`MessageRouter`] that can only route to a directly connected [`Destination`]. +#[must_use] +#[repr(C)] +pub struct DefaultMessageRouter { + /// 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 nativeDefaultMessageRouter, + /// 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 DefaultMessageRouter { + fn drop(&mut self) { + if self.is_owned && !<*mut nativeDefaultMessageRouter>::is_null(self.inner) { + let _ = unsafe { Box::from_raw(ObjOps::untweak_ptr(self.inner)) }; + } + } +} +/// Frees any resources used by the DefaultMessageRouter, if is_owned is set and inner is non-NULL. +#[no_mangle] +pub extern "C" fn DefaultMessageRouter_free(this_obj: DefaultMessageRouter) { } +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn DefaultMessageRouter_free_void(this_ptr: *mut c_void) { + let _ = unsafe { Box::from_raw(this_ptr as *mut nativeDefaultMessageRouter) }; +} +#[allow(unused)] +impl DefaultMessageRouter { + pub(crate) fn get_native_ref(&self) -> &'static nativeDefaultMessageRouter { + unsafe { &*ObjOps::untweak_ptr(self.inner) } + } + pub(crate) fn get_native_mut_ref(&self) -> &'static mut nativeDefaultMessageRouter { + unsafe { &mut *ObjOps::untweak_ptr(self.inner) } + } + /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy + pub(crate) fn take_inner(mut self) -> *mut nativeDefaultMessageRouter { + assert!(self.is_owned); + let ret = ObjOps::untweak_ptr(self.inner); + self.inner = core::ptr::null_mut(); + ret + } +} +/// Creates a [`DefaultMessageRouter`] using the given [`NetworkGraph`]. +#[must_use] +#[no_mangle] +pub extern "C" fn DefaultMessageRouter_new(network_graph: &crate::lightning::routing::gossip::NetworkGraph, mut entropy_source: crate::lightning::sign::EntropySource) -> crate::lightning::onion_message::messenger::DefaultMessageRouter { + let mut ret = lightning::onion_message::messenger::DefaultMessageRouter::new(network_graph.get_native_ref(), entropy_source); + crate::lightning::onion_message::messenger::DefaultMessageRouter { inner: ObjOps::heap_alloc(ret), is_owned: true } +} + +impl From for crate::lightning::onion_message::messenger::MessageRouter { + fn from(obj: nativeDefaultMessageRouter) -> Self { + let rust_obj = crate::lightning::onion_message::messenger::DefaultMessageRouter { inner: ObjOps::heap_alloc(obj), is_owned: true }; + let mut ret = DefaultMessageRouter_as_MessageRouter(&rust_obj); + // We want to free rust_obj when ret gets drop()'d, not rust_obj, so forget it and set ret's free() fn + core::mem::forget(rust_obj); + ret.free = Some(DefaultMessageRouter_free_void); + ret + } +} +/// Constructs a new MessageRouter which calls the relevant methods on this_arg. +/// This copies the `inner` pointer in this_arg and thus the returned MessageRouter must be freed before this_arg is +#[no_mangle] +pub extern "C" fn DefaultMessageRouter_as_MessageRouter(this_arg: &DefaultMessageRouter) -> crate::lightning::onion_message::messenger::MessageRouter { + crate::lightning::onion_message::messenger::MessageRouter { + this_arg: unsafe { ObjOps::untweak_ptr((*this_arg).inner) as *mut c_void }, + free: None, + find_path: DefaultMessageRouter_MessageRouter_find_path, + create_blinded_paths: DefaultMessageRouter_MessageRouter_create_blinded_paths, + } +} + +#[must_use] +extern "C" fn DefaultMessageRouter_MessageRouter_find_path(this_arg: *const c_void, mut sender: crate::c_types::PublicKey, mut peers: crate::c_types::derived::CVec_PublicKeyZ, mut destination: crate::lightning::onion_message::messenger::Destination) -> crate::c_types::derived::CResult_OnionMessagePathNoneZ { + let mut local_peers = Vec::new(); for mut item in peers.into_rust().drain(..) { local_peers.push( { item.into_rust() }); }; + let mut ret = >::find_path(unsafe { &mut *(this_arg as *mut nativeDefaultMessageRouter) }, sender.into_rust(), local_peers, destination.into_native()); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::onion_message::messenger::OnionMessagePath { inner: ObjOps::heap_alloc(o), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { () /*e*/ }).into() }; + local_ret +} +#[must_use] +extern "C" fn DefaultMessageRouter_MessageRouter_create_blinded_paths(this_arg: *const c_void, mut recipient: crate::c_types::PublicKey, mut peers: crate::c_types::derived::CVec_PublicKeyZ) -> crate::c_types::derived::CResult_CVec_BlindedPathZNoneZ { + let mut local_peers = Vec::new(); for mut item in peers.into_rust().drain(..) { local_peers.push( { item.into_rust() }); }; + let mut ret = >::create_blinded_paths(unsafe { &mut *(this_arg as *mut nativeDefaultMessageRouter) }, recipient.into_rust(), local_peers, secp256k1::global::SECP256K1); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let mut local_ret_0 = Vec::new(); for mut item in o.drain(..) { local_ret_0.push( { crate::lightning::blinded_path::BlindedPath { inner: ObjOps::heap_alloc(item), is_owned: true } }); }; local_ret_0.into() }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { () /*e*/ }).into() }; + local_ret +} + + +use lightning::onion_message::messenger::OnionMessagePath as nativeOnionMessagePathImport; +pub(crate) type nativeOnionMessagePath = nativeOnionMessagePathImport; + +/// A path for sending an [`OnionMessage`]. +#[must_use] +#[repr(C)] +pub struct OnionMessagePath { + /// 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 nativeOnionMessagePath, + /// 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 OnionMessagePath { + fn drop(&mut self) { + if self.is_owned && !<*mut nativeOnionMessagePath>::is_null(self.inner) { + let _ = unsafe { Box::from_raw(ObjOps::untweak_ptr(self.inner)) }; + } + } +} +/// Frees any resources used by the OnionMessagePath, if is_owned is set and inner is non-NULL. +#[no_mangle] +pub extern "C" fn OnionMessagePath_free(this_obj: OnionMessagePath) { } +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn OnionMessagePath_free_void(this_ptr: *mut c_void) { + let _ = unsafe { Box::from_raw(this_ptr as *mut nativeOnionMessagePath) }; +} +#[allow(unused)] +impl OnionMessagePath { + pub(crate) fn get_native_ref(&self) -> &'static nativeOnionMessagePath { + unsafe { &*ObjOps::untweak_ptr(self.inner) } + } + pub(crate) fn get_native_mut_ref(&self) -> &'static mut nativeOnionMessagePath { + unsafe { &mut *ObjOps::untweak_ptr(self.inner) } + } + /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy + pub(crate) fn take_inner(mut self) -> *mut nativeOnionMessagePath { + assert!(self.is_owned); + let ret = ObjOps::untweak_ptr(self.inner); + self.inner = core::ptr::null_mut(); + ret + } +} +/// Nodes on the path between the sender and the destination. +/// +/// Returns a copy of the field. +#[no_mangle] +pub extern "C" fn OnionMessagePath_get_intermediate_nodes(this_ptr: &OnionMessagePath) -> crate::c_types::derived::CVec_PublicKeyZ { + let mut inner_val = this_ptr.get_native_mut_ref().intermediate_nodes.clone(); + let mut local_inner_val = Vec::new(); for mut item in inner_val.drain(..) { local_inner_val.push( { crate::c_types::PublicKey::from_rust(&item) }); }; + local_inner_val.into() +} +/// Nodes on the path between the sender and the destination. +#[no_mangle] +pub extern "C" fn OnionMessagePath_set_intermediate_nodes(this_ptr: &mut OnionMessagePath, mut val: crate::c_types::derived::CVec_PublicKeyZ) { + let mut local_val = Vec::new(); for mut item in val.into_rust().drain(..) { local_val.push( { item.into_rust() }); }; + unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.intermediate_nodes = local_val; +} +/// The recipient of the message. +#[no_mangle] +pub extern "C" fn OnionMessagePath_get_destination(this_ptr: &OnionMessagePath) -> crate::lightning::onion_message::messenger::Destination { + let mut inner_val = &mut this_ptr.get_native_mut_ref().destination; + crate::lightning::onion_message::messenger::Destination::from_native(inner_val) +} +/// The recipient of the message. +#[no_mangle] +pub extern "C" fn OnionMessagePath_set_destination(this_ptr: &mut OnionMessagePath, mut val: crate::lightning::onion_message::messenger::Destination) { + unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.destination = val.into_native(); +} +/// Addresses that may be used to connect to [`OnionMessagePath::first_node`]. +/// +/// Only needs to be set if a connection to the node is required. [`OnionMessenger`] may use +/// this to initiate such a connection. +/// +/// Returns a copy of the field. +#[no_mangle] +pub extern "C" fn OnionMessagePath_get_first_node_addresses(this_ptr: &OnionMessagePath) -> crate::c_types::derived::COption_CVec_SocketAddressZZ { + let mut inner_val = this_ptr.get_native_mut_ref().first_node_addresses.clone(); + let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_CVec_SocketAddressZZ::None } else { crate::c_types::derived::COption_CVec_SocketAddressZZ::Some( { let mut local_inner_val_0 = Vec::new(); for mut item in inner_val.unwrap().drain(..) { local_inner_val_0.push( { crate::lightning::ln::msgs::SocketAddress::native_into(item) }); }; local_inner_val_0.into() }) }; + local_inner_val +} +/// Addresses that may be used to connect to [`OnionMessagePath::first_node`]. +/// +/// Only needs to be set if a connection to the node is required. [`OnionMessenger`] may use +/// this to initiate such a connection. +#[no_mangle] +pub extern "C" fn OnionMessagePath_set_first_node_addresses(this_ptr: &mut OnionMessagePath, mut val: crate::c_types::derived::COption_CVec_SocketAddressZZ) { + let mut local_val = { /*val*/ let val_opt = val; if val_opt.is_none() { None } else { Some({ { let mut local_val_0 = Vec::new(); for mut item in { val_opt.take() }.into_rust().drain(..) { local_val_0.push( { item.into_native() }); }; local_val_0 }})} }; + unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.first_node_addresses = local_val; +} +/// Constructs a new OnionMessagePath given each field +#[must_use] +#[no_mangle] +pub extern "C" fn OnionMessagePath_new(mut intermediate_nodes_arg: crate::c_types::derived::CVec_PublicKeyZ, mut destination_arg: crate::lightning::onion_message::messenger::Destination, mut first_node_addresses_arg: crate::c_types::derived::COption_CVec_SocketAddressZZ) -> OnionMessagePath { + let mut local_intermediate_nodes_arg = Vec::new(); for mut item in intermediate_nodes_arg.into_rust().drain(..) { local_intermediate_nodes_arg.push( { item.into_rust() }); }; + let mut local_first_node_addresses_arg = { /*first_node_addresses_arg*/ let first_node_addresses_arg_opt = first_node_addresses_arg; if first_node_addresses_arg_opt.is_none() { None } else { Some({ { let mut local_first_node_addresses_arg_0 = Vec::new(); for mut item in { first_node_addresses_arg_opt.take() }.into_rust().drain(..) { local_first_node_addresses_arg_0.push( { item.into_native() }); }; local_first_node_addresses_arg_0 }})} }; + OnionMessagePath { inner: ObjOps::heap_alloc(nativeOnionMessagePath { + intermediate_nodes: local_intermediate_nodes_arg, + destination: destination_arg.into_native(), + first_node_addresses: local_first_node_addresses_arg, + }), is_owned: true } +} +impl Clone for OnionMessagePath { + fn clone(&self) -> Self { + Self { + inner: if <*mut nativeOnionMessagePath>::is_null(self.inner) { core::ptr::null_mut() } else { + ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(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 OnionMessagePath_clone_void(this_ptr: *const c_void) -> *mut c_void { + Box::into_raw(Box::new(unsafe { (*(this_ptr as *const nativeOnionMessagePath)).clone() })) as *mut c_void +} +#[no_mangle] +/// Creates a copy of the OnionMessagePath +pub extern "C" fn OnionMessagePath_clone(orig: &OnionMessagePath) -> OnionMessagePath { + orig.clone() +} +/// Returns the first node in the path. +#[must_use] +#[no_mangle] +pub extern "C" fn OnionMessagePath_first_node(this_arg: &crate::lightning::onion_message::messenger::OnionMessagePath) -> crate::c_types::PublicKey { + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.first_node(); + crate::c_types::PublicKey::from_rust(&ret) +} + /// The destination of an onion message. +#[derive(Clone)] #[must_use] #[repr(C)] pub enum Destination { /// We're sending this onion message to a node. Node( crate::c_types::PublicKey), - /// We're sending this onion message to a blinded route. - BlindedRoute( - crate::lightning::onion_message::blinded_route::BlindedRoute), + /// We're sending this onion message to a blinded path. + BlindedPath( + crate::lightning::blinded_path::BlindedPath), } use lightning::onion_message::messenger::Destination as DestinationImport; pub(crate) type nativeDestination = DestinationImport; impl Destination { + #[allow(unused)] + pub(crate) fn to_native(&self) -> nativeDestination { + match self { + Destination::Node (ref a, ) => { + let mut a_nonref = Clone::clone(a); + nativeDestination::Node ( + a_nonref.into_rust(), + ) + }, + Destination::BlindedPath (ref a, ) => { + let mut a_nonref = Clone::clone(a); + nativeDestination::BlindedPath ( + *unsafe { Box::from_raw(a_nonref.take_inner()) }, + ) + }, + } + } #[allow(unused)] pub(crate) fn into_native(self) -> nativeDestination { match self { @@ -142,14 +516,32 @@ impl Destination { a.into_rust(), ) }, - Destination::BlindedRoute (mut a, ) => { - nativeDestination::BlindedRoute ( + Destination::BlindedPath (mut a, ) => { + nativeDestination::BlindedPath ( *unsafe { Box::from_raw(a.take_inner()) }, ) }, } } #[allow(unused)] + pub(crate) fn from_native(native: &DestinationImport) -> Self { + let native = unsafe { &*(native as *const _ as *const c_void as *const nativeDestination) }; + match native { + nativeDestination::Node (ref a, ) => { + let mut a_nonref = Clone::clone(a); + Destination::Node ( + crate::c_types::PublicKey::from_rust(&a_nonref), + ) + }, + nativeDestination::BlindedPath (ref a, ) => { + let mut a_nonref = Clone::clone(a); + Destination::BlindedPath ( + crate::lightning::blinded_path::BlindedPath { inner: ObjOps::heap_alloc(a_nonref), is_owned: true }, + ) + }, + } + } + #[allow(unused)] pub(crate) fn native_into(native: nativeDestination) -> Self { match native { nativeDestination::Node (mut a, ) => { @@ -157,9 +549,9 @@ impl Destination { crate::c_types::PublicKey::from_rust(&a), ) }, - nativeDestination::BlindedRoute (mut a, ) => { - Destination::BlindedRoute ( - crate::lightning::onion_message::blinded_route::BlindedRoute { inner: ObjOps::heap_alloc(a), is_owned: true }, + nativeDestination::BlindedPath (mut a, ) => { + Destination::BlindedPath ( + crate::lightning::blinded_path::BlindedPath { inner: ObjOps::heap_alloc(a), is_owned: true }, ) }, } @@ -168,15 +560,133 @@ impl Destination { /// Frees any resources used by the Destination #[no_mangle] pub extern "C" fn Destination_free(this_ptr: Destination) { } +/// Creates a copy of the Destination +#[no_mangle] +pub extern "C" fn Destination_clone(orig: &Destination) -> Destination { + orig.clone() +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn Destination_clone_void(this_ptr: *const c_void) -> *mut c_void { + Box::into_raw(Box::new(unsafe { (*(this_ptr as *const Destination)).clone() })) as *mut c_void +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn Destination_free_void(this_ptr: *mut c_void) { + let _ = unsafe { Box::from_raw(this_ptr as *mut Destination) }; +} #[no_mangle] /// Utility method to constructs a new Node-variant Destination pub extern "C" fn Destination_node(a: crate::c_types::PublicKey) -> Destination { Destination::Node(a, ) } #[no_mangle] -/// Utility method to constructs a new BlindedRoute-variant Destination -pub extern "C" fn Destination_blinded_route(a: crate::lightning::onion_message::blinded_route::BlindedRoute) -> Destination { - Destination::BlindedRoute(a, ) +/// Utility method to constructs a new BlindedPath-variant Destination +pub extern "C" fn Destination_blinded_path(a: crate::lightning::blinded_path::BlindedPath) -> Destination { + Destination::BlindedPath(a, ) +} +/// Result of successfully [sending an onion message]. +/// +/// [sending an onion message]: OnionMessenger::send_onion_message +#[derive(Clone)] +#[must_use] +#[repr(C)] +pub enum SendSuccess { + /// The message was buffered and will be sent once it is processed by + /// [`OnionMessageHandler::next_onion_message_for_peer`]. + Buffered, + /// The message was buffered and will be sent once the node is connected as a peer and it is + /// processed by [`OnionMessageHandler::next_onion_message_for_peer`]. + BufferedAwaitingConnection( + crate::c_types::PublicKey), +} +use lightning::onion_message::messenger::SendSuccess as SendSuccessImport; +pub(crate) type nativeSendSuccess = SendSuccessImport; + +impl SendSuccess { + #[allow(unused)] + pub(crate) fn to_native(&self) -> nativeSendSuccess { + match self { + SendSuccess::Buffered => nativeSendSuccess::Buffered, + SendSuccess::BufferedAwaitingConnection (ref a, ) => { + let mut a_nonref = Clone::clone(a); + nativeSendSuccess::BufferedAwaitingConnection ( + a_nonref.into_rust(), + ) + }, + } + } + #[allow(unused)] + pub(crate) fn into_native(self) -> nativeSendSuccess { + match self { + SendSuccess::Buffered => nativeSendSuccess::Buffered, + SendSuccess::BufferedAwaitingConnection (mut a, ) => { + nativeSendSuccess::BufferedAwaitingConnection ( + a.into_rust(), + ) + }, + } + } + #[allow(unused)] + pub(crate) fn from_native(native: &SendSuccessImport) -> Self { + let native = unsafe { &*(native as *const _ as *const c_void as *const nativeSendSuccess) }; + match native { + nativeSendSuccess::Buffered => SendSuccess::Buffered, + nativeSendSuccess::BufferedAwaitingConnection (ref a, ) => { + let mut a_nonref = Clone::clone(a); + SendSuccess::BufferedAwaitingConnection ( + crate::c_types::PublicKey::from_rust(&a_nonref), + ) + }, + } + } + #[allow(unused)] + pub(crate) fn native_into(native: nativeSendSuccess) -> Self { + match native { + nativeSendSuccess::Buffered => SendSuccess::Buffered, + nativeSendSuccess::BufferedAwaitingConnection (mut a, ) => { + SendSuccess::BufferedAwaitingConnection ( + crate::c_types::PublicKey::from_rust(&a), + ) + }, + } + } +} +/// Frees any resources used by the SendSuccess +#[no_mangle] +pub extern "C" fn SendSuccess_free(this_ptr: SendSuccess) { } +/// Creates a copy of the SendSuccess +#[no_mangle] +pub extern "C" fn SendSuccess_clone(orig: &SendSuccess) -> SendSuccess { + orig.clone() +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn SendSuccess_clone_void(this_ptr: *const c_void) -> *mut c_void { + Box::into_raw(Box::new(unsafe { (*(this_ptr as *const SendSuccess)).clone() })) as *mut c_void +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn SendSuccess_free_void(this_ptr: *mut c_void) { + let _ = unsafe { Box::from_raw(this_ptr as *mut SendSuccess) }; +} +#[no_mangle] +/// Utility method to constructs a new Buffered-variant SendSuccess +pub extern "C" fn SendSuccess_buffered() -> SendSuccess { + SendSuccess::Buffered} +#[no_mangle] +/// Utility method to constructs a new BufferedAwaitingConnection-variant SendSuccess +pub extern "C" fn SendSuccess_buffered_awaiting_connection(a: crate::c_types::PublicKey) -> SendSuccess { + SendSuccess::BufferedAwaitingConnection(a, ) +} +/// Get a string which allows debug introspection of a SendSuccess object +pub extern "C" fn SendSuccess_debug_str_void(o: *const c_void) -> Str { + alloc::format!("{:?}", unsafe { o as *const crate::lightning::onion_message::messenger::SendSuccess }).into()} +/// Checks if two SendSuccesss contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn SendSuccess_eq(a: &SendSuccess, b: &SendSuccess) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } } /// Errors that may occur when [sending an onion message]. /// @@ -191,13 +701,27 @@ pub enum SendError { /// Because implementations such as Eclair will drop onion messages where the message packet /// exceeds 32834 bytes, we refuse to send messages where the packet exceeds this size. TooBigPacket, - /// The provided [`Destination`] was an invalid [`BlindedRoute`], due to having fewer than two - /// blinded hops. + /// The provided [`Destination`] was an invalid [`BlindedPath`] due to not having any blinded + /// hops. TooFewBlindedHops, - /// Our next-hop peer was offline or does not support onion message forwarding. - InvalidFirstHop, + /// The first hop is not a peer and doesn't have a known [`SocketAddress`]. + InvalidFirstHop( + crate::c_types::PublicKey), + /// A path from the sender to the destination could not be found by the [`MessageRouter`]. + PathNotFound, + /// Onion message contents must have a TLV type >= 64. + InvalidMessage, /// Our next-hop peer's buffer was full or our total outbound buffer was full. BufferFull, + /// Failed to retrieve our node id from the provided [`NodeSigner`]. + /// + /// [`NodeSigner`]: crate::sign::NodeSigner + GetNodeIdFailed, + /// We attempted to send to a blinded path where we are the introduction node, and failed to + /// advance the blinded path to make the second hop the new introduction node. Either + /// [`NodeSigner::ecdh`] failed, we failed to tweak the current blinding point to get the + /// new blinding point, or we were attempting to send to ourselves. + BlindedPathAdvanceFailed, } use lightning::onion_message::messenger::SendError as SendErrorImport; pub(crate) type nativeSendError = SendErrorImport; @@ -207,15 +731,24 @@ impl SendError { pub(crate) fn to_native(&self) -> nativeSendError { match self { SendError::Secp256k1 (ref a, ) => { - let mut a_nonref = (*a).clone(); + let mut a_nonref = Clone::clone(a); nativeSendError::Secp256k1 ( a_nonref.into_rust(), ) }, SendError::TooBigPacket => nativeSendError::TooBigPacket, SendError::TooFewBlindedHops => nativeSendError::TooFewBlindedHops, - SendError::InvalidFirstHop => nativeSendError::InvalidFirstHop, + SendError::InvalidFirstHop (ref a, ) => { + let mut a_nonref = Clone::clone(a); + nativeSendError::InvalidFirstHop ( + a_nonref.into_rust(), + ) + }, + SendError::PathNotFound => nativeSendError::PathNotFound, + SendError::InvalidMessage => nativeSendError::InvalidMessage, SendError::BufferFull => nativeSendError::BufferFull, + SendError::GetNodeIdFailed => nativeSendError::GetNodeIdFailed, + SendError::BlindedPathAdvanceFailed => nativeSendError::BlindedPathAdvanceFailed, } } #[allow(unused)] @@ -228,23 +761,41 @@ impl SendError { }, SendError::TooBigPacket => nativeSendError::TooBigPacket, SendError::TooFewBlindedHops => nativeSendError::TooFewBlindedHops, - SendError::InvalidFirstHop => nativeSendError::InvalidFirstHop, + SendError::InvalidFirstHop (mut a, ) => { + nativeSendError::InvalidFirstHop ( + a.into_rust(), + ) + }, + SendError::PathNotFound => nativeSendError::PathNotFound, + SendError::InvalidMessage => nativeSendError::InvalidMessage, SendError::BufferFull => nativeSendError::BufferFull, + SendError::GetNodeIdFailed => nativeSendError::GetNodeIdFailed, + SendError::BlindedPathAdvanceFailed => nativeSendError::BlindedPathAdvanceFailed, } } #[allow(unused)] - pub(crate) fn from_native(native: &nativeSendError) -> Self { + pub(crate) fn from_native(native: &SendErrorImport) -> Self { + let native = unsafe { &*(native as *const _ as *const c_void as *const nativeSendError) }; match native { nativeSendError::Secp256k1 (ref a, ) => { - let mut a_nonref = (*a).clone(); + let mut a_nonref = Clone::clone(a); SendError::Secp256k1 ( crate::c_types::Secp256k1Error::from_rust(a_nonref), ) }, nativeSendError::TooBigPacket => SendError::TooBigPacket, nativeSendError::TooFewBlindedHops => SendError::TooFewBlindedHops, - nativeSendError::InvalidFirstHop => SendError::InvalidFirstHop, + nativeSendError::InvalidFirstHop (ref a, ) => { + let mut a_nonref = Clone::clone(a); + SendError::InvalidFirstHop ( + crate::c_types::PublicKey::from_rust(&a_nonref), + ) + }, + nativeSendError::PathNotFound => SendError::PathNotFound, + nativeSendError::InvalidMessage => SendError::InvalidMessage, nativeSendError::BufferFull => SendError::BufferFull, + nativeSendError::GetNodeIdFailed => SendError::GetNodeIdFailed, + nativeSendError::BlindedPathAdvanceFailed => SendError::BlindedPathAdvanceFailed, } } #[allow(unused)] @@ -257,8 +808,16 @@ impl SendError { }, nativeSendError::TooBigPacket => SendError::TooBigPacket, nativeSendError::TooFewBlindedHops => SendError::TooFewBlindedHops, - nativeSendError::InvalidFirstHop => SendError::InvalidFirstHop, + nativeSendError::InvalidFirstHop (mut a, ) => { + SendError::InvalidFirstHop ( + crate::c_types::PublicKey::from_rust(&a), + ) + }, + nativeSendError::PathNotFound => SendError::PathNotFound, + nativeSendError::InvalidMessage => SendError::InvalidMessage, nativeSendError::BufferFull => SendError::BufferFull, + nativeSendError::GetNodeIdFailed => SendError::GetNodeIdFailed, + nativeSendError::BlindedPathAdvanceFailed => SendError::BlindedPathAdvanceFailed, } } } @@ -270,6 +829,16 @@ pub extern "C" fn SendError_free(this_ptr: SendError) { } pub extern "C" fn SendError_clone(orig: &SendError) -> SendError { orig.clone() } +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn SendError_clone_void(this_ptr: *const c_void) -> *mut c_void { + Box::into_raw(Box::new(unsafe { (*(this_ptr as *const SendError)).clone() })) as *mut c_void +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn SendError_free_void(this_ptr: *mut c_void) { + let _ = unsafe { Box::from_raw(this_ptr as *mut SendError) }; +} #[no_mangle] /// Utility method to constructs a new Secp256k1-variant SendError pub extern "C" fn SendError_secp256k1(a: crate::c_types::Secp256k1Error) -> SendError { @@ -285,41 +854,324 @@ pub extern "C" fn SendError_too_few_blinded_hops() -> SendError { SendError::TooFewBlindedHops} #[no_mangle] /// Utility method to constructs a new InvalidFirstHop-variant SendError -pub extern "C" fn SendError_invalid_first_hop() -> SendError { - SendError::InvalidFirstHop} +pub extern "C" fn SendError_invalid_first_hop(a: crate::c_types::PublicKey) -> SendError { + SendError::InvalidFirstHop(a, ) +} +#[no_mangle] +/// Utility method to constructs a new PathNotFound-variant SendError +pub extern "C" fn SendError_path_not_found() -> SendError { + SendError::PathNotFound} +#[no_mangle] +/// Utility method to constructs a new InvalidMessage-variant SendError +pub extern "C" fn SendError_invalid_message() -> SendError { + SendError::InvalidMessage} #[no_mangle] /// Utility method to constructs a new BufferFull-variant SendError pub extern "C" fn SendError_buffer_full() -> SendError { SendError::BufferFull} +#[no_mangle] +/// Utility method to constructs a new GetNodeIdFailed-variant SendError +pub extern "C" fn SendError_get_node_id_failed() -> SendError { + SendError::GetNodeIdFailed} +#[no_mangle] +/// Utility method to constructs a new BlindedPathAdvanceFailed-variant SendError +pub extern "C" fn SendError_blinded_path_advance_failed() -> SendError { + SendError::BlindedPathAdvanceFailed} +/// Get a string which allows debug introspection of a SendError object +pub extern "C" fn SendError_debug_str_void(o: *const c_void) -> Str { + alloc::format!("{:?}", unsafe { o as *const crate::lightning::onion_message::messenger::SendError }).into()} +/// Checks if two SendErrors contain equal inner contents. +/// This ignores pointers and is_owned flags and looks at the values in fields. +#[no_mangle] +pub extern "C" fn SendError_eq(a: &SendError, b: &SendError) -> bool { + if &a.to_native() == &b.to_native() { true } else { false } +} +/// Handler for custom onion messages. If you are using [`SimpleArcOnionMessenger`], +/// [`SimpleRefOnionMessenger`], or prefer to ignore inbound custom onion messages, +/// [`IgnoringMessageHandler`] must be provided to [`OnionMessenger::new`]. Otherwise, a custom +/// implementation of this trait must be provided, with [`CustomMessage`] specifying the supported +/// message types. +/// +/// See [`OnionMessenger`] for example usage. +/// +/// [`IgnoringMessageHandler`]: crate::ln::peer_handler::IgnoringMessageHandler +/// [`CustomMessage`]: Self::CustomMessage +#[repr(C)] +pub struct CustomOnionMessageHandler { + /// An opaque pointer which is passed to your function implementations as an argument. + /// This has no meaning in the LDK, and can be NULL or any other value. + pub this_arg: *mut c_void, + /// Called with the custom message that was received, returning a response to send, if any. + /// + /// The returned [`Self::CustomMessage`], if any, is enqueued to be sent by [`OnionMessenger`]. + pub handle_custom_message: extern "C" fn (this_arg: *const c_void, msg: crate::lightning::onion_message::packet::OnionMessageContents) -> crate::c_types::derived::COption_OnionMessageContentsZ, + /// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the + /// message type is unknown. + pub read_custom_message: extern "C" fn (this_arg: *const c_void, message_type: u64, buffer: crate::c_types::u8slice) -> crate::c_types::derived::CResult_COption_OnionMessageContentsZDecodeErrorZ, + /// Releases any [`Self::CustomMessage`]s that need to be sent. + /// + /// Typically, this is used for messages initiating a message flow rather than in response to + /// another message. The latter should use the return value of [`Self::handle_custom_message`]. + pub release_pending_custom_messages: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_C3Tuple_OnionMessageContentsDestinationBlindedPathZZ, + /// Frees any resources associated with this object given its this_arg pointer. + /// Does not need to free the outer struct containing function pointers and may be NULL is no resources need to be freed. + pub free: Option, +} +unsafe impl Send for CustomOnionMessageHandler {} +unsafe impl Sync for CustomOnionMessageHandler {} +#[allow(unused)] +pub(crate) fn CustomOnionMessageHandler_clone_fields(orig: &CustomOnionMessageHandler) -> CustomOnionMessageHandler { + CustomOnionMessageHandler { + this_arg: orig.this_arg, + handle_custom_message: Clone::clone(&orig.handle_custom_message), + read_custom_message: Clone::clone(&orig.read_custom_message), + release_pending_custom_messages: Clone::clone(&orig.release_pending_custom_messages), + free: Clone::clone(&orig.free), + } +} + +use lightning::onion_message::messenger::CustomOnionMessageHandler as rustCustomOnionMessageHandler; +impl rustCustomOnionMessageHandler for CustomOnionMessageHandler { + type CustomMessage = crate::lightning::onion_message::packet::OnionMessageContents; + fn handle_custom_message(&self, mut msg: crate::lightning::onion_message::packet::OnionMessageContents) -> Option { + let mut ret = (self.handle_custom_message)(self.this_arg, Into::into(msg)); + let mut local_ret = { /*ret*/ let ret_opt = ret; if ret_opt.is_none() { None } else { Some({ { { ret_opt.take() } }})} }; + local_ret + } + fn read_custom_message(&self, mut message_type: u64, mut buffer: &mut R) -> Result, lightning::ln::msgs::DecodeError> { + let mut ret = (self.read_custom_message)(self.this_arg, message_type, crate::c_types::u8slice::from_vec(&crate::c_types::reader_to_vec(buffer))); + let mut local_ret = match ret.result_ok { true => Ok( { let mut local_ret_0 = { /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) })*/ let ret_0_opt = (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.result)) }); if ret_0_opt.is_none() { None } else { Some({ { { ret_0_opt.take() } }})} }; local_ret_0 }), false => Err( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut ret.contents.err)) }).into_native() })}; + local_ret + } + fn release_pending_custom_messages(&self) -> Vec<(crate::lightning::onion_message::packet::OnionMessageContents, lightning::onion_message::messenger::Destination, Option)> { + let mut ret = (self.release_pending_custom_messages)(self.this_arg); + let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { let (mut orig_ret_0_0, mut orig_ret_0_1, mut orig_ret_0_2) = item.to_rust(); let mut local_orig_ret_0_2 = if orig_ret_0_2.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(orig_ret_0_2.take_inner()) } }) }; let mut local_ret_0 = (orig_ret_0_0, orig_ret_0_1.into_native(), local_orig_ret_0_2); local_ret_0 }); }; + local_ret + } +} + +// We're essentially a pointer already, or at least a set of pointers, so allow us to be used +// directly as a Deref trait in higher-level structs: +impl core::ops::Deref for CustomOnionMessageHandler { + type Target = Self; + fn deref(&self) -> &Self { + self + } +} +impl core::ops::DerefMut for CustomOnionMessageHandler { + fn deref_mut(&mut self) -> &mut Self { + self + } +} +/// Calls the free function if one is set +#[no_mangle] +pub extern "C" fn CustomOnionMessageHandler_free(this_ptr: CustomOnionMessageHandler) { } +impl Drop for CustomOnionMessageHandler { + fn drop(&mut self) { + if let Some(f) = self.free { + f(self.this_arg); + } + } +} +/// A processed incoming onion message, containing either a Forward (another onion message) +/// or a Receive payload with decrypted contents. +#[derive(Clone)] +#[must_use] +#[repr(C)] +pub enum PeeledOnion { + /// Forwarded onion, with the next node id and a new onion + Forward( + crate::c_types::PublicKey, + crate::lightning::ln::msgs::OnionMessage), + /// Received onion message, with decrypted contents, path_id, and reply path + Receive( + crate::lightning::onion_message::packet::ParsedOnionMessageContents, + /// + /// Note that this (or a relevant inner pointer) may be NULL or all-0s to represent None + crate::c_types::ThirtyTwoBytes, + /// + /// Note that this (or a relevant inner pointer) may be NULL or all-0s to represent None + crate::lightning::blinded_path::BlindedPath), +} +use lightning::onion_message::messenger::PeeledOnion as PeeledOnionImport; +pub(crate) type nativePeeledOnion = PeeledOnionImport; + +impl PeeledOnion { + #[allow(unused)] + pub(crate) fn to_native(&self) -> nativePeeledOnion { + match self { + PeeledOnion::Forward (ref a, ref b, ) => { + let mut a_nonref = Clone::clone(a); + let mut b_nonref = Clone::clone(b); + nativePeeledOnion::Forward ( + a_nonref.into_rust(), + *unsafe { Box::from_raw(b_nonref.take_inner()) }, + ) + }, + PeeledOnion::Receive (ref a, ref b, ref c, ) => { + let mut a_nonref = Clone::clone(a); + let mut b_nonref = Clone::clone(b); + let mut local_b_nonref = if b_nonref.data == [0; 32] { None } else { Some( { b_nonref.data }) }; + let mut c_nonref = Clone::clone(c); + let mut local_c_nonref = if c_nonref.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(c_nonref.take_inner()) } }) }; + nativePeeledOnion::Receive ( + a_nonref.into_native(), + local_b_nonref, + local_c_nonref, + ) + }, + } + } + #[allow(unused)] + pub(crate) fn into_native(self) -> nativePeeledOnion { + match self { + PeeledOnion::Forward (mut a, mut b, ) => { + nativePeeledOnion::Forward ( + a.into_rust(), + *unsafe { Box::from_raw(b.take_inner()) }, + ) + }, + PeeledOnion::Receive (mut a, mut b, mut c, ) => { + let mut local_b = if b.data == [0; 32] { None } else { Some( { b.data }) }; + let mut local_c = if c.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(c.take_inner()) } }) }; + nativePeeledOnion::Receive ( + a.into_native(), + local_b, + local_c, + ) + }, + } + } + #[allow(unused)] + pub(crate) fn from_native(native: &PeeledOnionImport) -> Self { + let native = unsafe { &*(native as *const _ as *const c_void as *const nativePeeledOnion) }; + match native { + nativePeeledOnion::Forward (ref a, ref b, ) => { + let mut a_nonref = Clone::clone(a); + let mut b_nonref = Clone::clone(b); + PeeledOnion::Forward ( + crate::c_types::PublicKey::from_rust(&a_nonref), + crate::lightning::ln::msgs::OnionMessage { inner: ObjOps::heap_alloc(b_nonref), is_owned: true }, + ) + }, + nativePeeledOnion::Receive (ref a, ref b, ref c, ) => { + let mut a_nonref = Clone::clone(a); + let mut b_nonref = Clone::clone(b); + let mut local_b_nonref = if b_nonref.is_none() { crate::c_types::ThirtyTwoBytes { data: [0; 32] } } else { { crate::c_types::ThirtyTwoBytes { data: (b_nonref.unwrap()) } } }; + let mut c_nonref = Clone::clone(c); + let mut local_c_nonref = crate::lightning::blinded_path::BlindedPath { inner: if c_nonref.is_none() { core::ptr::null_mut() } else { { ObjOps::heap_alloc((c_nonref.unwrap())) } }, is_owned: true }; + PeeledOnion::Receive ( + crate::lightning::onion_message::packet::ParsedOnionMessageContents::native_into(a_nonref), + local_b_nonref, + local_c_nonref, + ) + }, + } + } + #[allow(unused)] + pub(crate) fn native_into(native: nativePeeledOnion) -> Self { + match native { + nativePeeledOnion::Forward (mut a, mut b, ) => { + PeeledOnion::Forward ( + crate::c_types::PublicKey::from_rust(&a), + crate::lightning::ln::msgs::OnionMessage { inner: ObjOps::heap_alloc(b), is_owned: true }, + ) + }, + nativePeeledOnion::Receive (mut a, mut b, mut c, ) => { + let mut local_b = if b.is_none() { crate::c_types::ThirtyTwoBytes { data: [0; 32] } } else { { crate::c_types::ThirtyTwoBytes { data: (b.unwrap()) } } }; + let mut local_c = crate::lightning::blinded_path::BlindedPath { inner: if c.is_none() { core::ptr::null_mut() } else { { ObjOps::heap_alloc((c.unwrap())) } }, is_owned: true }; + PeeledOnion::Receive ( + crate::lightning::onion_message::packet::ParsedOnionMessageContents::native_into(a), + local_b, + local_c, + ) + }, + } + } +} +/// Frees any resources used by the PeeledOnion +#[no_mangle] +pub extern "C" fn PeeledOnion_free(this_ptr: PeeledOnion) { } +/// Creates a copy of the PeeledOnion +#[no_mangle] +pub extern "C" fn PeeledOnion_clone(orig: &PeeledOnion) -> PeeledOnion { + orig.clone() +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn PeeledOnion_clone_void(this_ptr: *const c_void) -> *mut c_void { + Box::into_raw(Box::new(unsafe { (*(this_ptr as *const PeeledOnion)).clone() })) as *mut c_void +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn PeeledOnion_free_void(this_ptr: *mut c_void) { + let _ = unsafe { Box::from_raw(this_ptr as *mut PeeledOnion) }; +} +#[no_mangle] +/// Utility method to constructs a new Forward-variant PeeledOnion +pub extern "C" fn PeeledOnion_forward(a: crate::c_types::PublicKey,b: crate::lightning::ln::msgs::OnionMessage) -> PeeledOnion { + PeeledOnion::Forward(a, b, ) +} +#[no_mangle] +/// Utility method to constructs a new Receive-variant PeeledOnion +pub extern "C" fn PeeledOnion_receive(a: crate::lightning::onion_message::packet::ParsedOnionMessageContents,b: crate::c_types::ThirtyTwoBytes,c: crate::lightning::blinded_path::BlindedPath) -> PeeledOnion { + PeeledOnion::Receive(a, b, c, ) +} +/// Creates an [`OnionMessage`] with the given `contents` for sending to the destination of +/// `path`. +/// +/// Returns the node id of the peer to send the message to, the message itself, and any addresses +/// need to connect to the first node. +/// +/// Note that reply_path (or a relevant inner pointer) may be NULL or all-0s to represent None +#[no_mangle] +pub extern "C" fn create_onion_message(entropy_source: &crate::lightning::sign::EntropySource, node_signer: &crate::lightning::sign::NodeSigner, mut path: crate::lightning::onion_message::messenger::OnionMessagePath, mut contents: crate::lightning::onion_message::packet::OnionMessageContents, mut reply_path: crate::lightning::blinded_path::BlindedPath) -> crate::c_types::derived::CResult_C3Tuple_PublicKeyOnionMessageCOption_CVec_SocketAddressZZZSendErrorZ { + let mut local_reply_path = if reply_path.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(reply_path.take_inner()) } }) }; + let mut ret = lightning::onion_message::messenger::create_onion_message::(entropy_source, node_signer, secp256k1::global::SECP256K1, *unsafe { Box::from_raw(path.take_inner()) }, contents, local_reply_path); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1, mut orig_ret_0_2) = o; let mut local_orig_ret_0_2 = if orig_ret_0_2.is_none() { crate::c_types::derived::COption_CVec_SocketAddressZZ::None } else { crate::c_types::derived::COption_CVec_SocketAddressZZ::Some( { let mut local_orig_ret_0_2_0 = Vec::new(); for mut item in orig_ret_0_2.unwrap().drain(..) { local_orig_ret_0_2_0.push( { crate::lightning::ln::msgs::SocketAddress::native_into(item) }); }; local_orig_ret_0_2_0.into() }) }; let mut local_ret_0 = (crate::c_types::PublicKey::from_rust(&orig_ret_0_0), crate::lightning::ln::msgs::OnionMessage { inner: ObjOps::heap_alloc(orig_ret_0_1), is_owned: true }, local_orig_ret_0_2).into(); local_ret_0 }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::onion_message::messenger::SendError::native_into(e) }).into() }; + local_ret +} + +/// Decode one layer of an incoming [`OnionMessage`]. +/// +/// Returns either the next layer of the onion for forwarding or the decrypted content for the +/// receiver. +#[no_mangle] +pub extern "C" fn peel_onion_message(msg: &crate::lightning::ln::msgs::OnionMessage, mut node_signer: crate::lightning::sign::NodeSigner, mut logger: crate::lightning::util::logger::Logger, mut custom_handler: crate::lightning::onion_message::messenger::CustomOnionMessageHandler) -> crate::c_types::derived::CResult_PeeledOnionNoneZ { + let mut ret = lightning::onion_message::messenger::peel_onion_message::(msg.get_native_ref(), secp256k1::global::SECP256K1, node_signer, logger, custom_handler); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::onion_message::messenger::PeeledOnion::native_into(o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { () /*e*/ }).into() }; + local_ret +} + /// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to /// their respective handlers. #[must_use] #[no_mangle] -pub extern "C" fn OnionMessenger_new(mut keys_manager: crate::lightning::chain::keysinterface::KeysInterface, mut logger: crate::lightning::util::logger::Logger) -> crate::lightning::onion_message::messenger::OnionMessenger { - let mut ret = lightning::onion_message::messenger::OnionMessenger::new(keys_manager, logger); +pub extern "C" fn OnionMessenger_new(mut entropy_source: crate::lightning::sign::EntropySource, mut node_signer: crate::lightning::sign::NodeSigner, mut logger: crate::lightning::util::logger::Logger, mut message_router: crate::lightning::onion_message::messenger::MessageRouter, mut offers_handler: crate::lightning::onion_message::offers::OffersMessageHandler, mut custom_handler: crate::lightning::onion_message::messenger::CustomOnionMessageHandler) -> crate::lightning::onion_message::messenger::OnionMessenger { + let mut ret = lightning::onion_message::messenger::OnionMessenger::new(entropy_source, node_signer, logger, message_router, offers_handler, custom_handler); crate::lightning::onion_message::messenger::OnionMessenger { inner: ObjOps::heap_alloc(ret), is_owned: true } } -/// Send an empty onion message to `destination`, routing it through `intermediate_nodes`. +/// Sends an [`OnionMessage`] with the given `contents` to `destination`. +/// /// See [`OnionMessenger`] for example usage. /// /// Note that reply_path (or a relevant inner pointer) may be NULL or all-0s to represent None #[must_use] #[no_mangle] -pub extern "C" fn OnionMessenger_send_onion_message(this_arg: &crate::lightning::onion_message::messenger::OnionMessenger, mut intermediate_nodes: crate::c_types::derived::CVec_PublicKeyZ, mut destination: crate::lightning::onion_message::messenger::Destination, mut reply_path: crate::lightning::onion_message::blinded_route::BlindedRoute) -> crate::c_types::derived::CResult_NoneSendErrorZ { - let mut local_intermediate_nodes = Vec::new(); for mut item in intermediate_nodes.into_rust().drain(..) { local_intermediate_nodes.push( { item.into_rust() }); }; +pub extern "C" fn OnionMessenger_send_onion_message(this_arg: &crate::lightning::onion_message::messenger::OnionMessenger, mut contents: crate::lightning::onion_message::packet::OnionMessageContents, mut destination: crate::lightning::onion_message::messenger::Destination, mut reply_path: crate::lightning::blinded_path::BlindedPath) -> crate::c_types::derived::CResult_SendSuccessSendErrorZ { let mut local_reply_path = if reply_path.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(reply_path.take_inner()) } }) }; - let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.send_onion_message(&local_intermediate_nodes[..], destination.into_native(), local_reply_path); - let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { () /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::onion_message::messenger::SendError::native_into(e) }).into() }; + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.send_onion_message(contents, destination.into_native(), local_reply_path); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::onion_message::messenger::SendSuccess::native_into(o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::onion_message::messenger::SendError::native_into(e) }).into() }; local_ret } impl From for crate::lightning::ln::msgs::OnionMessageHandler { fn from(obj: nativeOnionMessenger) -> Self { - let mut rust_obj = OnionMessenger { inner: ObjOps::heap_alloc(obj), is_owned: true }; + let rust_obj = crate::lightning::onion_message::messenger::OnionMessenger { inner: ObjOps::heap_alloc(obj), is_owned: true }; let mut ret = OnionMessenger_as_OnionMessageHandler(&rust_obj); - // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn - rust_obj.inner = core::ptr::null_mut(); + // We want to free rust_obj when ret gets drop()'d, not rust_obj, so forget it and set ret's free() fn + core::mem::forget(rust_obj); ret.free = Some(OnionMessenger_free_void); ret } @@ -331,27 +1183,43 @@ pub extern "C" fn OnionMessenger_as_OnionMessageHandler(this_arg: &OnionMessenge crate::lightning::ln::msgs::OnionMessageHandler { this_arg: unsafe { ObjOps::untweak_ptr((*this_arg).inner) as *mut c_void }, free: None, + get_and_clear_connections_needed: OnionMessenger_OnionMessageHandler_get_and_clear_connections_needed, handle_onion_message: OnionMessenger_OnionMessageHandler_handle_onion_message, + next_onion_message_for_peer: OnionMessenger_OnionMessageHandler_next_onion_message_for_peer, peer_connected: OnionMessenger_OnionMessageHandler_peer_connected, peer_disconnected: OnionMessenger_OnionMessageHandler_peer_disconnected, + timer_tick_occurred: OnionMessenger_OnionMessageHandler_timer_tick_occurred, provided_node_features: OnionMessenger_OnionMessageHandler_provided_node_features, provided_init_features: OnionMessenger_OnionMessageHandler_provided_init_features, - OnionMessageProvider: crate::lightning::util::events::OnionMessageProvider { - this_arg: unsafe { ObjOps::untweak_ptr((*this_arg).inner) as *mut c_void }, - free: None, - next_onion_message_for_peer: OnionMessenger_OnionMessageProvider_next_onion_message_for_peer, - }, } } +#[must_use] +extern "C" fn OnionMessenger_OnionMessageHandler_get_and_clear_connections_needed(this_arg: *const c_void) -> crate::c_types::derived::CVec_C2Tuple_PublicKeyCVec_SocketAddressZZZ { + let mut ret = >::get_and_clear_connections_needed(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, ); + let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { let (mut orig_ret_0_0, mut orig_ret_0_1) = item; let mut local_orig_ret_0_1 = Vec::new(); for mut item in orig_ret_0_1.drain(..) { local_orig_ret_0_1.push( { crate::lightning::ln::msgs::SocketAddress::native_into(item) }); }; let mut local_ret_0 = (crate::c_types::PublicKey::from_rust(&orig_ret_0_0), local_orig_ret_0_1.into()).into(); local_ret_0 }); }; + local_ret.into() +} extern "C" fn OnionMessenger_OnionMessageHandler_handle_onion_message(this_arg: *const c_void, mut peer_node_id: crate::c_types::PublicKey, msg: &crate::lightning::ln::msgs::OnionMessage) { >::handle_onion_message(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, &peer_node_id.into_rust(), msg.get_native_ref()) } -extern "C" fn OnionMessenger_OnionMessageHandler_peer_connected(this_arg: *const c_void, mut their_node_id: crate::c_types::PublicKey, init: &crate::lightning::ln::msgs::Init) { - >::peer_connected(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, &their_node_id.into_rust(), init.get_native_ref()) +#[must_use] +extern "C" fn OnionMessenger_OnionMessageHandler_next_onion_message_for_peer(this_arg: *const c_void, mut peer_node_id: crate::c_types::PublicKey) -> crate::lightning::ln::msgs::OnionMessage { + let mut ret = >::next_onion_message_for_peer(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, peer_node_id.into_rust()); + let mut local_ret = crate::lightning::ln::msgs::OnionMessage { inner: if ret.is_none() { core::ptr::null_mut() } else { { ObjOps::heap_alloc((ret.unwrap())) } }, is_owned: true }; + local_ret +} +#[must_use] +extern "C" fn OnionMessenger_OnionMessageHandler_peer_connected(this_arg: *const c_void, mut their_node_id: crate::c_types::PublicKey, init: &crate::lightning::ln::msgs::Init, mut inbound: bool) -> crate::c_types::derived::CResult_NoneNoneZ { + let mut ret = >::peer_connected(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, &their_node_id.into_rust(), init.get_native_ref(), inbound); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { () /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { () /*e*/ }).into() }; + local_ret } -extern "C" fn OnionMessenger_OnionMessageHandler_peer_disconnected(this_arg: *const c_void, mut their_node_id: crate::c_types::PublicKey, mut no_connection_possible: bool) { - >::peer_disconnected(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, &their_node_id.into_rust(), no_connection_possible) +extern "C" fn OnionMessenger_OnionMessageHandler_peer_disconnected(this_arg: *const c_void, mut their_node_id: crate::c_types::PublicKey) { + >::peer_disconnected(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, &their_node_id.into_rust()) +} +extern "C" fn OnionMessenger_OnionMessageHandler_timer_tick_occurred(this_arg: *const c_void) { + >::timer_tick_occurred(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, ) } #[must_use] extern "C" fn OnionMessenger_OnionMessageHandler_provided_node_features(this_arg: *const c_void) -> crate::lightning::ln::features::NodeFeatures { @@ -364,31 +1232,3 @@ extern "C" fn OnionMessenger_OnionMessageHandler_provided_init_features(this_arg crate::lightning::ln::features::InitFeatures { inner: ObjOps::heap_alloc(ret), is_owned: true } } -impl From for crate::lightning::util::events::OnionMessageProvider { - fn from(obj: nativeOnionMessenger) -> Self { - let mut rust_obj = OnionMessenger { inner: ObjOps::heap_alloc(obj), is_owned: true }; - let mut ret = OnionMessenger_as_OnionMessageProvider(&rust_obj); - // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn - rust_obj.inner = core::ptr::null_mut(); - ret.free = Some(OnionMessenger_free_void); - ret - } -} -/// Constructs a new OnionMessageProvider which calls the relevant methods on this_arg. -/// This copies the `inner` pointer in this_arg and thus the returned OnionMessageProvider must be freed before this_arg is -#[no_mangle] -pub extern "C" fn OnionMessenger_as_OnionMessageProvider(this_arg: &OnionMessenger) -> crate::lightning::util::events::OnionMessageProvider { - crate::lightning::util::events::OnionMessageProvider { - this_arg: unsafe { ObjOps::untweak_ptr((*this_arg).inner) as *mut c_void }, - free: None, - next_onion_message_for_peer: OnionMessenger_OnionMessageProvider_next_onion_message_for_peer, - } -} - -#[must_use] -extern "C" fn OnionMessenger_OnionMessageProvider_next_onion_message_for_peer(this_arg: *const c_void, mut peer_node_id: crate::c_types::PublicKey) -> crate::lightning::ln::msgs::OnionMessage { - let mut ret = >::next_onion_message_for_peer(unsafe { &mut *(this_arg as *mut nativeOnionMessenger) }, peer_node_id.into_rust()); - let mut local_ret = crate::lightning::ln::msgs::OnionMessage { inner: if ret.is_none() { core::ptr::null_mut() } else { { ObjOps::heap_alloc((ret.unwrap())) } }, is_owned: true }; - local_ret -} -