X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-c-bindings;a=blobdiff_plain;f=lightning-c-bindings%2Fsrc%2Flightning%2Fln%2Fchannelmanager.rs;h=3910df368f073a0dde7734247517bd47695c699c;hp=871d9e523902ea46a203f9eeefad3c4884237969;hb=1eaf50a3d9f777b462ff1817678473567a00eb75;hpb=fee27c4b40d1d25609a38bb220dd64b297af929a diff --git a/lightning-c-bindings/src/lightning/ln/channelmanager.rs b/lightning-c-bindings/src/lightning/ln/channelmanager.rs index 871d9e5..3910df3 100644 --- a/lightning-c-bindings/src/lightning/ln/channelmanager.rs +++ b/lightning-c-bindings/src/lightning/ln/channelmanager.rs @@ -17,120 +17,28 @@ //! imply it needs to fail HTLCs/payments/channels it manages). //! -use std::str::FromStr; -use std::ffi::c_void; +use alloc::str::FromStr; +use core::ffi::c_void; use core::convert::Infallible; use bitcoin::hashes::Hash; use crate::c_types::*; +#[cfg(feature="no-std")] +use alloc::{vec::Vec, boxed::Box}; +mod inbound_payment { -use lightning::ln::channelmanager::PaymentId as nativePaymentIdImport; -type nativePaymentId = nativePaymentIdImport; - -/// A payment identifier used to uniquely identify a payment to LDK. -#[must_use] -#[repr(C)] -pub struct PaymentId { - /// 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 nativePaymentId, - /// Indicates that this is the only struct which contains the same pointer. +use alloc::str::FromStr; +use core::ffi::c_void; +use core::convert::Infallible; +use bitcoin::hashes::Hash; +use crate::c_types::*; +#[cfg(feature="no-std")] +use alloc::{vec::Vec, boxed::Box}; - /// 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 PaymentId { - fn drop(&mut self) { - if self.is_owned && !<*mut nativePaymentId>::is_null(self.inner) { - let _ = unsafe { Box::from_raw(ObjOps::untweak_ptr(self.inner)) }; - } - } -} -/// Frees any resources used by the PaymentId, if is_owned is set and inner is non-NULL. -#[no_mangle] -pub extern "C" fn PaymentId_free(this_obj: PaymentId) { } -#[allow(unused)] -/// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn PaymentId_free_void(this_ptr: *mut c_void) { - unsafe { let _ = Box::from_raw(this_ptr as *mut nativePaymentId); } -} -#[allow(unused)] -impl PaymentId { - pub(crate) fn get_native_ref(&self) -> &'static nativePaymentId { - unsafe { &*ObjOps::untweak_ptr(self.inner) } - } - pub(crate) fn get_native_mut_ref(&self) -> &'static mut nativePaymentId { - 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 nativePaymentId { - assert!(self.is_owned); - let ret = ObjOps::untweak_ptr(self.inner); - self.inner = std::ptr::null_mut(); - ret - } -} -/// Checks if two PaymentIds contain equal inner contents. -#[no_mangle] -pub extern "C" fn PaymentId_hash(o: &PaymentId) -> u64 { - if o.inner.is_null() { return 0; } - // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core - #[allow(deprecated)] - let mut hasher = core::hash::SipHasher::new(); - std::hash::Hash::hash(o.get_native_ref(), &mut hasher); - std::hash::Hasher::finish(&hasher) -} -impl Clone for PaymentId { - fn clone(&self) -> Self { - Self { - inner: if <*mut nativePaymentId>::is_null(self.inner) { std::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 PaymentId_clone_void(this_ptr: *const c_void) -> *mut c_void { - Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativePaymentId)).clone() })) as *mut c_void -} -#[no_mangle] -/// Creates a copy of the PaymentId -pub extern "C" fn PaymentId_clone(orig: &PaymentId) -> PaymentId { - orig.clone() -} -/// Checks if two PaymentIds contain equal inner contents. -/// This ignores pointers and is_owned flags and looks at the values in fields. -/// Two objects with NULL inner values will be considered "equal" here. -#[no_mangle] -pub extern "C" fn PaymentId_eq(a: &PaymentId, b: &PaymentId) -> bool { - if a.inner == b.inner { return true; } - if a.inner.is_null() || b.inner.is_null() { return false; } - if a.get_native_ref() == b.get_native_ref() { true } else { false } -} -#[no_mangle] -/// Serialize the PaymentId object into a byte array which can be read by PaymentId_read -pub extern "C" fn PaymentId_write(obj: &PaymentId) -> crate::c_types::derived::CVec_u8Z { - crate::c_types::serialize_obj(unsafe { &*obj }.get_native_ref()) -} -#[no_mangle] -pub(crate) extern "C" fn PaymentId_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z { - crate::c_types::serialize_obj(unsafe { &*(obj as *const nativePaymentId) }) -} -#[no_mangle] -/// Read a PaymentId from a byte array, created by PaymentId_write -pub extern "C" fn PaymentId_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_PaymentIdDecodeErrorZ { - let res = crate::c_types::deserialize_obj(ser); - let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::ln::channelmanager::PaymentId { inner: ObjOps::heap_alloc(o), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::msgs::DecodeError { inner: ObjOps::heap_alloc(e), is_owned: true } }).into() }; - local_res } use lightning::ln::channelmanager::ChannelManager as nativeChannelManagerImport; -type nativeChannelManager = nativeChannelManagerImport; +pub(crate) type nativeChannelManager = nativeChannelManagerImport; /// Manager which keeps track of a number of channels and sends messages to the appropriate /// channel, also tracking HTLC preimages and forwarding onion packets appropriately. @@ -195,7 +103,7 @@ impl Drop for ChannelManager { pub extern "C" fn ChannelManager_free(this_obj: ChannelManager) { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn ChannelManager_free_void(this_ptr: *mut c_void) { +pub(crate) extern "C" fn ChannelManager_free_void(this_ptr: *mut c_void) { unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelManager); } } #[allow(unused)] @@ -210,13 +118,13 @@ impl ChannelManager { pub(crate) fn take_inner(mut self) -> *mut nativeChannelManager { assert!(self.is_owned); let ret = ObjOps::untweak_ptr(self.inner); - self.inner = std::ptr::null_mut(); + self.inner = core::ptr::null_mut(); ret } } use lightning::ln::channelmanager::ChainParameters as nativeChainParametersImport; -type nativeChainParameters = nativeChainParametersImport; +pub(crate) type nativeChainParameters = nativeChainParametersImport; /// Chain-related parameters used to construct a new `ChannelManager`. /// @@ -250,7 +158,7 @@ impl Drop for ChainParameters { pub extern "C" fn ChainParameters_free(this_obj: ChainParameters) { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn ChainParameters_free_void(this_ptr: *mut c_void) { +pub(crate) extern "C" fn ChainParameters_free_void(this_ptr: *mut c_void) { unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChainParameters); } } #[allow(unused)] @@ -265,7 +173,7 @@ impl ChainParameters { pub(crate) fn take_inner(mut self) -> *mut nativeChainParameters { assert!(self.is_owned); let ret = ObjOps::untweak_ptr(self.inner); - self.inner = std::ptr::null_mut(); + self.inner = core::ptr::null_mut(); ret } } @@ -286,7 +194,7 @@ pub extern "C" fn ChainParameters_set_network(this_ptr: &mut ChainParameters, mu #[no_mangle] pub extern "C" fn ChainParameters_get_best_block(this_ptr: &ChainParameters) -> crate::lightning::chain::BestBlock { let mut inner_val = &mut this_ptr.get_native_mut_ref().best_block; - crate::lightning::chain::BestBlock { inner: unsafe { ObjOps::nonnull_ptr_to_inner((inner_val as *const _) as *mut _) }, is_owned: false } + crate::lightning::chain::BestBlock { inner: unsafe { ObjOps::nonnull_ptr_to_inner((inner_val as *const lightning::chain::BestBlock<>) as *mut _) }, is_owned: false } } /// The hash and height of the latest block successfully connected. /// @@ -307,7 +215,7 @@ pub extern "C" fn ChainParameters_new(mut network_arg: crate::bitcoin::network:: impl Clone for ChainParameters { fn clone(&self) -> Self { Self { - inner: if <*mut nativeChainParameters>::is_null(self.inner) { std::ptr::null_mut() } else { + inner: if <*mut nativeChainParameters>::is_null(self.inner) { core::ptr::null_mut() } else { ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) }, is_owned: true, } @@ -349,7 +257,7 @@ pub static MIN_CLTV_EXPIRY_DELTA: u16 = lightning::ln::channelmanager::MIN_CLTV_ pub static MIN_FINAL_CLTV_EXPIRY: u32 = lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY; use lightning::ln::channelmanager::CounterpartyForwardingInfo as nativeCounterpartyForwardingInfoImport; -type nativeCounterpartyForwardingInfo = nativeCounterpartyForwardingInfoImport; +pub(crate) type nativeCounterpartyForwardingInfo = nativeCounterpartyForwardingInfoImport; /// Information needed for constructing an invoice route hint for this channel. #[must_use] @@ -379,7 +287,7 @@ impl Drop for CounterpartyForwardingInfo { pub extern "C" fn CounterpartyForwardingInfo_free(this_obj: CounterpartyForwardingInfo) { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn CounterpartyForwardingInfo_free_void(this_ptr: *mut c_void) { +pub(crate) extern "C" fn CounterpartyForwardingInfo_free_void(this_ptr: *mut c_void) { unsafe { let _ = Box::from_raw(this_ptr as *mut nativeCounterpartyForwardingInfo); } } #[allow(unused)] @@ -394,7 +302,7 @@ impl CounterpartyForwardingInfo { pub(crate) fn take_inner(mut self) -> *mut nativeCounterpartyForwardingInfo { assert!(self.is_owned); let ret = ObjOps::untweak_ptr(self.inner); - self.inner = std::ptr::null_mut(); + self.inner = core::ptr::null_mut(); ret } } @@ -448,7 +356,7 @@ pub extern "C" fn CounterpartyForwardingInfo_new(mut fee_base_msat_arg: u32, mut impl Clone for CounterpartyForwardingInfo { fn clone(&self) -> Self { Self { - inner: if <*mut nativeCounterpartyForwardingInfo>::is_null(self.inner) { std::ptr::null_mut() } else { + inner: if <*mut nativeCounterpartyForwardingInfo>::is_null(self.inner) { core::ptr::null_mut() } else { ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) }, is_owned: true, } @@ -466,7 +374,7 @@ pub extern "C" fn CounterpartyForwardingInfo_clone(orig: &CounterpartyForwarding } use lightning::ln::channelmanager::ChannelCounterparty as nativeChannelCounterpartyImport; -type nativeChannelCounterparty = nativeChannelCounterpartyImport; +pub(crate) type nativeChannelCounterparty = nativeChannelCounterpartyImport; /// Channel parameters which apply to our counterparty. These are split out from [`ChannelDetails`] /// to better separate parameters. @@ -497,7 +405,7 @@ impl Drop for ChannelCounterparty { 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 ChannelCounterparty_free_void(this_ptr: *mut c_void) { +pub(crate) extern "C" fn ChannelCounterparty_free_void(this_ptr: *mut c_void) { unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelCounterparty); } } #[allow(unused)] @@ -512,7 +420,7 @@ impl ChannelCounterparty { pub(crate) fn take_inner(mut self) -> *mut nativeChannelCounterparty { assert!(self.is_owned); let ret = ObjOps::untweak_ptr(self.inner); - self.inner = std::ptr::null_mut(); + self.inner = core::ptr::null_mut(); ret } } @@ -533,7 +441,7 @@ pub extern "C" fn ChannelCounterparty_set_node_id(this_ptr: &mut ChannelCounterp #[no_mangle] pub extern "C" fn ChannelCounterparty_get_features(this_ptr: &ChannelCounterparty) -> crate::lightning::ln::features::InitFeatures { let mut inner_val = &mut this_ptr.get_native_mut_ref().features; - crate::lightning::ln::features::InitFeatures { inner: unsafe { ObjOps::nonnull_ptr_to_inner((inner_val as *const _) as *mut _) }, is_owned: false } + crate::lightning::ln::features::InitFeatures { inner: unsafe { ObjOps::nonnull_ptr_to_inner((inner_val as *const lightning::ln::features::InitFeatures<>) 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 @@ -572,7 +480,7 @@ pub extern "C" fn ChannelCounterparty_set_unspendable_punishment_reserve(this_pt #[no_mangle] pub extern "C" fn ChannelCounterparty_get_forwarding_info(this_ptr: &ChannelCounterparty) -> crate::lightning::ln::channelmanager::CounterpartyForwardingInfo { let mut inner_val = &mut this_ptr.get_native_mut_ref().forwarding_info; - let mut local_inner_val = crate::lightning::ln::channelmanager::CounterpartyForwardingInfo { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (inner_val.as_ref().unwrap()) }) } as *const _) as *mut _ }, is_owned: false }; + let mut local_inner_val = crate::lightning::ln::channelmanager::CounterpartyForwardingInfo { inner: unsafe { (if inner_val.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (inner_val.as_ref().unwrap()) }) } as *const lightning::ln::channelmanager::CounterpartyForwardingInfo<>) as *mut _ }, is_owned: false }; local_inner_val } /// Information on the fees and requirements that the counterparty requires when forwarding @@ -599,7 +507,7 @@ pub extern "C" fn ChannelCounterparty_new(mut node_id_arg: crate::c_types::Publi impl Clone for ChannelCounterparty { fn clone(&self) -> Self { Self { - inner: if <*mut nativeChannelCounterparty>::is_null(self.inner) { std::ptr::null_mut() } else { + inner: if <*mut nativeChannelCounterparty>::is_null(self.inner) { core::ptr::null_mut() } else { ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) }, is_owned: true, } @@ -617,7 +525,7 @@ pub extern "C" fn ChannelCounterparty_clone(orig: &ChannelCounterparty) -> Chann } use lightning::ln::channelmanager::ChannelDetails as nativeChannelDetailsImport; -type nativeChannelDetails = nativeChannelDetailsImport; +pub(crate) type nativeChannelDetails = nativeChannelDetailsImport; /// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels #[must_use] @@ -647,7 +555,7 @@ impl Drop for ChannelDetails { pub extern "C" fn ChannelDetails_free(this_obj: ChannelDetails) { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn ChannelDetails_free_void(this_ptr: *mut c_void) { +pub(crate) extern "C" fn ChannelDetails_free_void(this_ptr: *mut c_void) { unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelDetails); } } #[allow(unused)] @@ -662,7 +570,7 @@ impl ChannelDetails { pub(crate) fn take_inner(mut self) -> *mut nativeChannelDetails { assert!(self.is_owned); let ret = ObjOps::untweak_ptr(self.inner); - self.inner = std::ptr::null_mut(); + self.inner = core::ptr::null_mut(); ret } } @@ -687,7 +595,7 @@ pub extern "C" fn ChannelDetails_set_channel_id(this_ptr: &mut ChannelDetails, m #[no_mangle] pub extern "C" fn ChannelDetails_get_counterparty(this_ptr: &ChannelDetails) -> crate::lightning::ln::channelmanager::ChannelCounterparty { let mut inner_val = &mut this_ptr.get_native_mut_ref().counterparty; - crate::lightning::ln::channelmanager::ChannelCounterparty { inner: unsafe { ObjOps::nonnull_ptr_to_inner((inner_val as *const _) as *mut _) }, is_owned: false } + crate::lightning::ln::channelmanager::ChannelCounterparty { inner: unsafe { ObjOps::nonnull_ptr_to_inner((inner_val as *const lightning::ln::channelmanager::ChannelCounterparty<>) as *mut _) }, is_owned: false } } /// Parameters which apply to our counterparty. See individual fields for more information. #[no_mangle] @@ -704,7 +612,7 @@ pub extern "C" fn ChannelDetails_set_counterparty(this_ptr: &mut ChannelDetails, #[no_mangle] pub extern "C" fn ChannelDetails_get_funding_txo(this_ptr: &ChannelDetails) -> crate::lightning::chain::transaction::OutPoint { let mut inner_val = &mut this_ptr.get_native_mut_ref().funding_txo; - let mut local_inner_val = crate::lightning::chain::transaction::OutPoint { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (inner_val.as_ref().unwrap()) }) } as *const _) as *mut _ }, is_owned: false }; + let mut local_inner_val = crate::lightning::chain::transaction::OutPoint { inner: unsafe { (if inner_val.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (inner_val.as_ref().unwrap()) }) } as *const lightning::chain::transaction::OutPoint<>) as *mut _ }, is_owned: false }; local_inner_val } /// The Channel's funding transaction output, if we've negotiated the funding transaction with @@ -785,11 +693,42 @@ pub extern "C" fn ChannelDetails_get_user_channel_id(this_ptr: &ChannelDetails) pub extern "C" fn ChannelDetails_set_user_channel_id(this_ptr: &mut ChannelDetails, mut val: u64) { unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.user_channel_id = val; } +/// Our total balance. This is the amount we would get if we close the channel. +/// This value is not exact. Due to various in-flight changes and feerate changes, exactly this +/// amount is not likely to be recoverable on close. +/// +/// This does not include any pending HTLCs which are not yet fully resolved (and, thus, whose +/// 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 does not consider any on-chain fees. +/// +/// See also [`ChannelDetails::outbound_capacity_msat`] +#[no_mangle] +pub extern "C" fn ChannelDetails_get_balance_msat(this_ptr: &ChannelDetails) -> u64 { + let mut inner_val = &mut this_ptr.get_native_mut_ref().balance_msat; + *inner_val +} +/// Our total balance. This is the amount we would get if we close the channel. +/// This value is not exact. Due to various in-flight changes and feerate changes, exactly this +/// amount is not likely to be recoverable on close. +/// +/// This does not include any pending HTLCs which are not yet fully resolved (and, thus, whose +/// 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 does not consider any on-chain fees. +/// +/// See also [`ChannelDetails::outbound_capacity_msat`] +#[no_mangle] +pub extern "C" fn ChannelDetails_set_balance_msat(this_ptr: &mut ChannelDetails, mut val: u64) { + unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.balance_msat = val; +} /// The available outbound capacity for sending HTLCs to the remote peer. This does not include -/// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not +/// any pending HTLCs which are not yet fully resolved (and, thus, whose 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. /// +/// See also [`ChannelDetails::balance_msat`] +/// /// 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. @@ -799,10 +738,12 @@ pub extern "C" fn ChannelDetails_get_outbound_capacity_msat(this_ptr: &ChannelDe *inner_val } /// The available outbound capacity for sending HTLCs to the remote peer. This does not include -/// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not +/// any pending HTLCs which are not yet fully resolved (and, thus, whose 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. /// +/// See also [`ChannelDetails::balance_msat`] +/// /// 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. @@ -811,7 +752,7 @@ pub extern "C" fn ChannelDetails_set_outbound_capacity_msat(this_ptr: &mut Chann unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.outbound_capacity_msat = val; } /// The available inbound capacity for the remote peer to send HTLCs to us. This does not -/// include any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not +/// include any pending HTLCs which are not yet fully resolved (and, thus, whose balance is not /// available for inclusion in new inbound HTLCs). /// Note that there are some corner cases not fully handled here, so the actual available /// inbound capacity may be slightly higher than this. @@ -825,7 +766,7 @@ pub extern "C" fn ChannelDetails_get_inbound_capacity_msat(this_ptr: &ChannelDet *inner_val } /// The available inbound capacity for the remote peer to send HTLCs to us. This does not -/// include any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not +/// include any pending HTLCs which are not yet fully resolved (and, thus, whose balance is not /// available for inclusion in new inbound HTLCs). /// Note that there are some corner cases not fully handled here, so the actual available /// inbound capacity may be slightly higher than this. @@ -960,7 +901,7 @@ pub extern "C" fn ChannelDetails_set_is_public(this_ptr: &mut ChannelDetails, mu /// 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_channel_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 { +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_channel_id_arg: u64, mut balance_msat_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 }; @@ -974,6 +915,7 @@ pub extern "C" fn ChannelDetails_new(mut channel_id_arg: crate::c_types::ThirtyT channel_value_satoshis: channel_value_satoshis_arg, unspendable_punishment_reserve: local_unspendable_punishment_reserve_arg, user_channel_id: user_channel_id_arg, + balance_msat: balance_msat_arg, outbound_capacity_msat: outbound_capacity_msat_arg, inbound_capacity_msat: inbound_capacity_msat_arg, confirmations_required: local_confirmations_required_arg, @@ -987,7 +929,7 @@ pub extern "C" fn ChannelDetails_new(mut channel_id_arg: crate::c_types::ThirtyT impl Clone for ChannelDetails { fn clone(&self) -> Self { Self { - inner: if <*mut nativeChannelDetails>::is_null(self.inner) { std::ptr::null_mut() } else { + inner: if <*mut nativeChannelDetails>::is_null(self.inner) { core::ptr::null_mut() } else { ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) }, is_owned: true, } @@ -1038,7 +980,18 @@ pub enum PaymentSendFailure { /// as they will result in over-/re-payment. These HTLCs all either successfully sent (in the /// case of Ok(())) or will send once channel_monitor_updated is called on the next-hop channel /// with the latest update_id. - PartialFailure(crate::c_types::derived::CVec_CResult_NoneAPIErrorZZ), + PartialFailure { + /// The errors themselves, in the same order as the route hops. + results: crate::c_types::derived::CVec_CResult_NoneAPIErrorZZ, + /// If some paths failed without irrevocably committing to the new HTLC(s), this will + /// contain a [`RouteParameters`] object which can be used to calculate a new route that + /// will pay all remaining unpaid balance. + /// + /// Note that this (or a relevant inner pointer) may be NULL or all-0s to represent None + failed_paths_retry: crate::lightning::routing::router::RouteParameters, + /// The payment id for the payment, which is now at least partially pending. + payment_id: crate::c_types::ThirtyTwoBytes, + }, } use lightning::ln::channelmanager::PaymentSendFailure as nativePaymentSendFailure; impl PaymentSendFailure { @@ -1065,12 +1018,17 @@ impl PaymentSendFailure { local_a_nonref, ) }, - PaymentSendFailure::PartialFailure (ref a, ) => { - let mut a_nonref = (*a).clone(); - let mut local_a_nonref = Vec::new(); for mut item in a_nonref.into_rust().drain(..) { local_a_nonref.push( { let mut local_a_nonref_0 = match item.result_ok { true => Ok( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut item.contents.result)) })*/ }), false => Err( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut item.contents.err)) }).into_native() })}; local_a_nonref_0 }); }; - nativePaymentSendFailure::PartialFailure ( - local_a_nonref, - ) + PaymentSendFailure::PartialFailure {ref results, ref failed_paths_retry, ref payment_id, } => { + let mut results_nonref = (*results).clone(); + let mut local_results_nonref = Vec::new(); for mut item in results_nonref.into_rust().drain(..) { local_results_nonref.push( { let mut local_results_nonref_0 = match item.result_ok { true => Ok( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut item.contents.result)) })*/ }), false => Err( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut item.contents.err)) }).into_native() })}; local_results_nonref_0 }); }; + let mut failed_paths_retry_nonref = (*failed_paths_retry).clone(); + let mut local_failed_paths_retry_nonref = if failed_paths_retry_nonref.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(failed_paths_retry_nonref.take_inner()) } }) }; + let mut payment_id_nonref = (*payment_id).clone(); + nativePaymentSendFailure::PartialFailure { + results: local_results_nonref, + failed_paths_retry: local_failed_paths_retry_nonref, + payment_id: ::lightning::ln::channelmanager::PaymentId(payment_id_nonref.data), + } }, } } @@ -1094,11 +1052,14 @@ impl PaymentSendFailure { local_a, ) }, - PaymentSendFailure::PartialFailure (mut a, ) => { - let mut local_a = Vec::new(); for mut item in a.into_rust().drain(..) { local_a.push( { let mut local_a_0 = match item.result_ok { true => Ok( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut item.contents.result)) })*/ }), false => Err( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut item.contents.err)) }).into_native() })}; local_a_0 }); }; - nativePaymentSendFailure::PartialFailure ( - local_a, - ) + PaymentSendFailure::PartialFailure {mut results, mut failed_paths_retry, mut payment_id, } => { + let mut local_results = Vec::new(); for mut item in results.into_rust().drain(..) { local_results.push( { let mut local_results_0 = match item.result_ok { true => Ok( { () /*(*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut item.contents.result)) })*/ }), false => Err( { (*unsafe { Box::from_raw(<*mut _>::take_ptr(&mut item.contents.err)) }).into_native() })}; local_results_0 }); }; + let mut local_failed_paths_retry = if failed_paths_retry.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(failed_paths_retry.take_inner()) } }) }; + nativePaymentSendFailure::PartialFailure { + results: local_results, + failed_paths_retry: local_failed_paths_retry, + payment_id: ::lightning::ln::channelmanager::PaymentId(payment_id.data), + } }, } } @@ -1125,12 +1086,17 @@ impl PaymentSendFailure { local_a_nonref.into(), ) }, - nativePaymentSendFailure::PartialFailure (ref a, ) => { - let mut a_nonref = (*a).clone(); - let mut local_a_nonref = Vec::new(); for mut item in a_nonref.drain(..) { local_a_nonref.push( { let mut local_a_nonref_0 = match item { Ok(mut o) => crate::c_types::CResultTempl::ok( { () /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_a_nonref_0 }); }; - PaymentSendFailure::PartialFailure ( - local_a_nonref.into(), - ) + nativePaymentSendFailure::PartialFailure {ref results, ref failed_paths_retry, ref payment_id, } => { + let mut results_nonref = (*results).clone(); + let mut local_results_nonref = Vec::new(); for mut item in results_nonref.drain(..) { local_results_nonref.push( { let mut local_results_nonref_0 = match item { Ok(mut o) => crate::c_types::CResultTempl::ok( { () /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_results_nonref_0 }); }; + let mut failed_paths_retry_nonref = (*failed_paths_retry).clone(); + let mut local_failed_paths_retry_nonref = crate::lightning::routing::router::RouteParameters { inner: if failed_paths_retry_nonref.is_none() { core::ptr::null_mut() } else { { ObjOps::heap_alloc((failed_paths_retry_nonref.unwrap())) } }, is_owned: true }; + let mut payment_id_nonref = (*payment_id).clone(); + PaymentSendFailure::PartialFailure { + results: local_results_nonref.into(), + failed_paths_retry: local_failed_paths_retry_nonref, + payment_id: crate::c_types::ThirtyTwoBytes { data: payment_id_nonref.0 }, + } }, } } @@ -1154,11 +1120,14 @@ impl PaymentSendFailure { local_a.into(), ) }, - nativePaymentSendFailure::PartialFailure (mut a, ) => { - let mut local_a = Vec::new(); for mut item in a.drain(..) { local_a.push( { let mut local_a_0 = match item { Ok(mut o) => crate::c_types::CResultTempl::ok( { () /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_a_0 }); }; - PaymentSendFailure::PartialFailure ( - local_a.into(), - ) + nativePaymentSendFailure::PartialFailure {mut results, mut failed_paths_retry, mut payment_id, } => { + let mut local_results = Vec::new(); for mut item in results.drain(..) { local_results.push( { let mut local_results_0 = match item { Ok(mut o) => crate::c_types::CResultTempl::ok( { () /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_results_0 }); }; + let mut local_failed_paths_retry = crate::lightning::routing::router::RouteParameters { inner: if failed_paths_retry.is_none() { core::ptr::null_mut() } else { { ObjOps::heap_alloc((failed_paths_retry.unwrap())) } }, is_owned: true }; + PaymentSendFailure::PartialFailure { + results: local_results.into(), + failed_paths_retry: local_failed_paths_retry, + payment_id: crate::c_types::ThirtyTwoBytes { data: payment_id.0 }, + } }, } } @@ -1188,8 +1157,12 @@ pub extern "C" fn PaymentSendFailure_all_failed_retry_safe(a: crate::c_types::de } #[no_mangle] /// Utility method to constructs a new PartialFailure-variant PaymentSendFailure -pub extern "C" fn PaymentSendFailure_partial_failure(a: crate::c_types::derived::CVec_CResult_NoneAPIErrorZZ) -> PaymentSendFailure { - PaymentSendFailure::PartialFailure(a, ) +pub extern "C" fn PaymentSendFailure_partial_failure(results: crate::c_types::derived::CVec_CResult_NoneAPIErrorZZ, failed_paths_retry: crate::lightning::routing::router::RouteParameters, payment_id: crate::c_types::ThirtyTwoBytes) -> PaymentSendFailure { + PaymentSendFailure::PartialFailure { + results, + failed_paths_retry, + payment_id, + } } /// Constructs a new ChannelManager to hold several channels and route between them. /// @@ -1215,7 +1188,7 @@ pub extern "C" fn ChannelManager_new(mut fee_est: crate::lightning::chain::chain #[no_mangle] pub extern "C" fn ChannelManager_get_current_default_configuration(this_arg: &ChannelManager) -> crate::lightning::util::config::UserConfig { let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.get_current_default_configuration(); - crate::lightning::util::config::UserConfig { inner: unsafe { ObjOps::nonnull_ptr_to_inner((ret as *const _) as *mut _) }, is_owned: false } + crate::lightning::util::config::UserConfig { inner: unsafe { ObjOps::nonnull_ptr_to_inner((ret as *const lightning::util::config::UserConfig<>) as *mut _) }, is_owned: false } } /// Creates a new outbound channel to the given remote node and with the given value. @@ -1394,7 +1367,7 @@ pub extern "C" fn ChannelManager_force_close_all_channels(this_arg: &ChannelMana pub extern "C" fn ChannelManager_send_payment(this_arg: &ChannelManager, route: &crate::lightning::routing::router::Route, mut payment_hash: crate::c_types::ThirtyTwoBytes, mut payment_secret: crate::c_types::ThirtyTwoBytes) -> crate::c_types::derived::CResult_PaymentIdPaymentSendFailureZ { let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::PaymentSecret(payment_secret.data) }) }; let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.send_payment(route.get_native_ref(), ::lightning::ln::PaymentHash(payment_hash.data), &local_payment_secret); - let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning::ln::channelmanager::PaymentId { inner: ObjOps::heap_alloc(o), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::channelmanager::PaymentSendFailure::native_into(e) }).into() }; + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::ThirtyTwoBytes { data: o.0 } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::channelmanager::PaymentSendFailure::native_into(e) }).into() }; local_ret } @@ -1402,18 +1375,39 @@ pub extern "C" fn ChannelManager_send_payment(this_arg: &ChannelManager, route: /// /// Errors returned are a superset of those returned from [`send_payment`], so see /// [`send_payment`] documentation for more details on errors. This method will also error if the -/// retry amount puts the payment more than 10% over the payment's total amount, or if the payment -/// for the given `payment_id` cannot be found (likely due to timeout or success). +/// retry amount puts the payment more than 10% over the payment's total amount, if the payment +/// for the given `payment_id` cannot be found (likely due to timeout or success), or if +/// further retries have been disabled with [`abandon_payment`]. /// /// [`send_payment`]: [`ChannelManager::send_payment`] +/// [`abandon_payment`]: [`ChannelManager::abandon_payment`] #[must_use] #[no_mangle] -pub extern "C" fn ChannelManager_retry_payment(this_arg: &ChannelManager, route: &crate::lightning::routing::router::Route, mut payment_id: crate::lightning::ln::channelmanager::PaymentId) -> crate::c_types::derived::CResult_NonePaymentSendFailureZ { - let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.retry_payment(route.get_native_ref(), *unsafe { Box::from_raw(payment_id.take_inner()) }); +pub extern "C" fn ChannelManager_retry_payment(this_arg: &ChannelManager, route: &crate::lightning::routing::router::Route, mut payment_id: crate::c_types::ThirtyTwoBytes) -> crate::c_types::derived::CResult_NonePaymentSendFailureZ { + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.retry_payment(route.get_native_ref(), ::lightning::ln::channelmanager::PaymentId(payment_id.data)); 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::ln::channelmanager::PaymentSendFailure::native_into(e) }).into() }; local_ret } +/// Signals that no further retries for the given payment will occur. +/// +/// After this method returns, any future calls to [`retry_payment`] for the given `payment_id` +/// will fail with [`PaymentSendFailure::ParameterError`]. If no such event has been generated, +/// an [`Event::PaymentFailed`] event will be generated as soon as there are no remaining +/// pending HTLCs for this payment. +/// +/// Note that calling this method does *not* prevent a payment from succeeding. You must still +/// wait until you receive either a [`Event::PaymentFailed`] or [`Event::PaymentSent`] event to +/// determine the ultimate status of a payment. +/// +/// [`retry_payment`]: Self::retry_payment +/// [`Event::PaymentFailed`]: events::Event::PaymentFailed +/// [`Event::PaymentSent`]: events::Event::PaymentSent +#[no_mangle] +pub extern "C" fn ChannelManager_abandon_payment(this_arg: &ChannelManager, mut payment_id: crate::c_types::ThirtyTwoBytes) { + unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.abandon_payment(::lightning::ln::channelmanager::PaymentId(payment_id.data)) +} + /// Send a spontaneous payment, which is a payment that does not require the recipient to have /// generated an invoice. Optionally, you may specify the preimage. If you do choose to specify /// the preimage, it must be a cryptographically secure random value that no intermediate node @@ -1435,7 +1429,7 @@ pub extern "C" fn ChannelManager_retry_payment(this_arg: &ChannelManager, route: pub extern "C" fn ChannelManager_send_spontaneous_payment(this_arg: &ChannelManager, route: &crate::lightning::routing::router::Route, mut payment_preimage: crate::c_types::ThirtyTwoBytes) -> crate::c_types::derived::CResult_C2Tuple_PaymentHashPaymentIdZPaymentSendFailureZ { let mut local_payment_preimage = if payment_preimage.data == [0; 32] { None } else { Some( { ::lightning::ln::PaymentPreimage(payment_preimage.data) }) }; let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.send_spontaneous_payment(route.get_native_ref(), local_payment_preimage); - let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = o; let mut local_ret_0 = (crate::c_types::ThirtyTwoBytes { data: orig_ret_0_0.0 }, crate::lightning::ln::channelmanager::PaymentId { inner: ObjOps::heap_alloc(orig_ret_0_1), is_owned: true }).into(); local_ret_0 }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::channelmanager::PaymentSendFailure::native_into(e) }).into() }; + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = o; let mut local_ret_0 = (crate::c_types::ThirtyTwoBytes { data: orig_ret_0_0.0 }, crate::c_types::ThirtyTwoBytes { data: orig_ret_0_1.0 }).into(); local_ret_0 }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::channelmanager::PaymentSendFailure::native_into(e) }).into() }; local_ret } @@ -1444,7 +1438,8 @@ pub extern "C" fn ChannelManager_send_spontaneous_payment(this_arg: &ChannelMana /// Returns an [`APIError::APIMisuseError`] if the funding_transaction spent non-SegWit outputs /// or if no output was found which matches the parameters in [`Event::FundingGenerationReady`]. /// -/// Panics if a funding transaction has already been provided for this channel. +/// Returns [`APIError::ChannelUnavailable`] if a funding transaction has already been provided +/// for the channel or if the channel has been closed as indicated by [`Event::ChannelClosed`]. /// /// May panic if the output found in the funding transaction is duplicative with some other /// channel (note that this should be trivially prevented by using unique funding transaction @@ -1459,6 +1454,7 @@ pub extern "C" fn ChannelManager_send_spontaneous_payment(this_arg: &ChannelMana /// create a new channel with a conflicting funding transaction. /// /// [`Event::FundingGenerationReady`]: crate::util::events::Event::FundingGenerationReady +/// [`Event::ChannelClosed`]: crate::util::events::Event::ChannelClosed #[must_use] #[no_mangle] pub extern "C" fn ChannelManager_funding_transaction_generated(this_arg: &ChannelManager, temporary_channel_id: *const [u8; 32], mut funding_transaction: crate::c_types::Transaction) -> crate::c_types::derived::CResult_NoneAPIErrorZ { @@ -1527,19 +1523,21 @@ pub extern "C" fn ChannelManager_fail_htlc_backwards(this_arg: &ChannelManager, ret } -/// Provides a payment preimage in response to a PaymentReceived event, returning true and -/// generating message events for the net layer to claim the payment, if possible. Thus, you -/// should probably kick the net layer to go send messages if this returns true! +/// Provides a payment preimage in response to [`Event::PaymentReceived`], generating any +/// [`MessageSendEvent`]s needed to claim the payment. /// /// Note that if you did not set an `amount_msat` when calling [`create_inbound_payment`] or /// [`create_inbound_payment_for_hash`] you must check that the amount in the `PaymentReceived` /// event matches your expectation. If you fail to do so and call this method, you may provide /// the sender \"proof-of-payment\" when they did not fulfill the full expected payment. /// -/// May panic if called except in response to a PaymentReceived event. +/// Returns whether any HTLCs were claimed, and thus if any new [`MessageSendEvent`]s are now +/// pending for processing via [`get_and_clear_pending_msg_events`]. /// +/// [`Event::PaymentReceived`]: crate::util::events::Event::PaymentReceived /// [`create_inbound_payment`]: Self::create_inbound_payment /// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash +/// [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events #[must_use] #[no_mangle] pub extern "C" fn ChannelManager_claim_funds(this_arg: &ChannelManager, mut payment_preimage: crate::c_types::ThirtyTwoBytes) -> bool { @@ -1555,36 +1553,11 @@ pub extern "C" fn ChannelManager_get_our_node_id(this_arg: &ChannelManager) -> c crate::c_types::PublicKey::from_rust(&ret) } -/// Restores a single, given channel to normal operation after a -/// ChannelMonitorUpdateErr::TemporaryFailure was returned from a channel monitor update -/// operation. -/// -/// All ChannelMonitor updates up to and including highest_applied_update_id must have been -/// fully committed in every copy of the given channels' ChannelMonitors. -/// -/// Note that there is no effect to calling with a highest_applied_update_id other than the -/// current latest ChannelMonitorUpdate and one call to this function after multiple -/// ChannelMonitorUpdateErr::TemporaryFailures is fine. The highest_applied_update_id field -/// exists largely only to prevent races between this and concurrent update_monitor calls. -/// -/// Thus, the anticipated use is, at a high level: -/// 1) You register a chain::Watch with this ChannelManager, -/// 2) it stores each update to disk, and begins updating any remote (eg watchtower) copies of -/// said ChannelMonitors as it can, returning ChannelMonitorUpdateErr::TemporaryFailures -/// any time it cannot do so instantly, -/// 3) update(s) are applied to each remote copy of a ChannelMonitor, -/// 4) once all remote copies are updated, you call this function with the update_id that -/// completed, and once it is the latest the Channel will be re-enabled. -#[no_mangle] -pub extern "C" fn ChannelManager_channel_monitor_updated(this_arg: &ChannelManager, funding_txo: &crate::lightning::chain::transaction::OutPoint, mut highest_applied_update_id: u64) { - unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.channel_monitor_updated(funding_txo.get_native_ref(), highest_applied_update_id) -} - /// Gets a payment secret and payment hash for use in an invoice given to a third party wishing /// to pay us. /// /// This differs from [`create_inbound_payment_for_hash`] only in that it generates the -/// [`PaymentHash`] and [`PaymentPreimage`] for you, returning the first and storing the second. +/// [`PaymentHash`] and [`PaymentPreimage`] for you. /// /// The [`PaymentPreimage`] will ultimately be returned to you in the [`PaymentReceived`], which /// will have the [`PaymentReceived::payment_preimage`] field filled in. That should then be @@ -1592,16 +1565,42 @@ pub extern "C" fn ChannelManager_channel_monitor_updated(this_arg: &ChannelManag /// /// See [`create_inbound_payment_for_hash`] for detailed documentation on behavior and requirements. /// +/// Note that a malicious eavesdropper can intuit whether an inbound payment was created by +/// `create_inbound_payment` or `create_inbound_payment_for_hash` based on runtime. +/// +/// # Note +/// +/// If you register an inbound payment with this method, then serialize the `ChannelManager`, then +/// deserialize it with a node running 0.0.103 and earlier, the payment will fail to be received. +/// +/// Errors if `min_value_msat` is greater than total bitcoin supply. +/// /// [`claim_funds`]: Self::claim_funds /// [`PaymentReceived`]: events::Event::PaymentReceived /// [`PaymentReceived::payment_preimage`]: events::Event::PaymentReceived::payment_preimage /// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash #[must_use] #[no_mangle] -pub extern "C" fn ChannelManager_create_inbound_payment(this_arg: &ChannelManager, mut min_value_msat: crate::c_types::derived::COption_u64Z, mut invoice_expiry_delta_secs: u32, mut user_payment_id: u64) -> crate::c_types::derived::C2Tuple_PaymentHashPaymentSecretZ { +pub extern "C" fn ChannelManager_create_inbound_payment(this_arg: &ChannelManager, mut min_value_msat: crate::c_types::derived::COption_u64Z, mut invoice_expiry_delta_secs: u32) -> crate::c_types::derived::CResult_C2Tuple_PaymentHashPaymentSecretZNoneZ { let mut local_min_value_msat = if min_value_msat.is_some() { Some( { min_value_msat.take() }) } else { None }; - let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.create_inbound_payment(local_min_value_msat, invoice_expiry_delta_secs, user_payment_id); - let (mut orig_ret_0, mut orig_ret_1) = ret; let mut local_ret = (crate::c_types::ThirtyTwoBytes { data: orig_ret_0.0 }, crate::c_types::ThirtyTwoBytes { data: orig_ret_1.0 }).into(); + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.create_inbound_payment(local_min_value_msat, invoice_expiry_delta_secs); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = o; let mut local_ret_0 = (crate::c_types::ThirtyTwoBytes { data: orig_ret_0_0.0 }, crate::c_types::ThirtyTwoBytes { data: orig_ret_0_1.0 }).into(); local_ret_0 }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { () /*e*/ }).into() }; + local_ret +} + +/// Legacy version of [`create_inbound_payment`]. Use this method if you wish to share +/// serialized state with LDK node(s) running 0.0.103 and earlier. +/// +/// # Note +/// This method is deprecated and will be removed soon. +/// +/// [`create_inbound_payment`]: Self::create_inbound_payment +#[must_use] +#[no_mangle] +pub extern "C" fn ChannelManager_create_inbound_payment_legacy(this_arg: &ChannelManager, mut min_value_msat: crate::c_types::derived::COption_u64Z, mut invoice_expiry_delta_secs: u32) -> crate::c_types::derived::CResult_C2Tuple_PaymentHashPaymentSecretZAPIErrorZ { + let mut local_min_value_msat = if min_value_msat.is_some() { Some( { min_value_msat.take() }) } else { None }; + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.create_inbound_payment_legacy(local_min_value_msat, invoice_expiry_delta_secs); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let (mut orig_ret_0_0, mut orig_ret_0_1) = o; let mut local_ret_0 = (crate::c_types::ThirtyTwoBytes { data: orig_ret_0_0.0 }, crate::c_types::ThirtyTwoBytes { data: orig_ret_0_1.0 }).into(); local_ret_0 }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_ret } @@ -1612,14 +1611,9 @@ pub extern "C" fn ChannelManager_create_inbound_payment(this_arg: &ChannelManage /// payment secret fetched via this method or [`create_inbound_payment`], and which is at least /// the `min_value_msat` provided here, if one is provided. /// -/// The [`PaymentHash`] (and corresponding [`PaymentPreimage`]) must be globally unique. This -/// method may return an Err if another payment with the same payment_hash is still pending. -/// -/// `user_payment_id` will be provided back in [`PaymentPurpose::InvoicePayment::user_payment_id`] events to -/// allow tracking of which events correspond with which calls to this and -/// [`create_inbound_payment`]. `user_payment_id` has no meaning inside of LDK, it is simply -/// copied to events and otherwise ignored. It may be used to correlate PaymentReceived events -/// with invoice metadata stored elsewhere. +/// The [`PaymentHash`] (and corresponding [`PaymentPreimage`]) should be globally unique, though +/// note that LDK will not stop you from registering duplicate payment hashes for inbound +/// payments. /// /// `min_value_msat` should be set if the invoice being generated contains a value. Any payment /// received for the returned [`PaymentHash`] will be required to be at least `min_value_msat` @@ -1638,23 +1632,56 @@ pub extern "C" fn ChannelManager_create_inbound_payment(this_arg: &ChannelManage /// If you need exact expiry semantics, you should enforce them upon receipt of /// [`PaymentReceived`]. /// -/// Pending inbound payments are stored in memory and in serialized versions of this -/// [`ChannelManager`]. If potentially unbounded numbers of inbound payments may exist and -/// space is limited, you may wish to rate-limit inbound payment creation. -/// /// May panic if `invoice_expiry_delta_secs` is greater than one year. /// /// Note that invoices generated for inbound payments should have their `min_final_cltv_expiry` /// set to at least [`MIN_FINAL_CLTV_EXPIRY`]. /// +/// Note that a malicious eavesdropper can intuit whether an inbound payment was created by +/// `create_inbound_payment` or `create_inbound_payment_for_hash` based on runtime. +/// +/// # Note +/// +/// If you register an inbound payment with this method, then serialize the `ChannelManager`, then +/// deserialize it with a node running 0.0.103 and earlier, the payment will fail to be received. +/// +/// Errors if `min_value_msat` is greater than total bitcoin supply. +/// /// [`create_inbound_payment`]: Self::create_inbound_payment /// [`PaymentReceived`]: events::Event::PaymentReceived -/// [`PaymentPurpose::InvoicePayment::user_payment_id`]: events::PaymentPurpose::InvoicePayment::user_payment_id #[must_use] #[no_mangle] -pub extern "C" fn ChannelManager_create_inbound_payment_for_hash(this_arg: &ChannelManager, mut payment_hash: crate::c_types::ThirtyTwoBytes, mut min_value_msat: crate::c_types::derived::COption_u64Z, mut invoice_expiry_delta_secs: u32, mut user_payment_id: u64) -> crate::c_types::derived::CResult_PaymentSecretAPIErrorZ { +pub extern "C" fn ChannelManager_create_inbound_payment_for_hash(this_arg: &ChannelManager, mut payment_hash: crate::c_types::ThirtyTwoBytes, mut min_value_msat: crate::c_types::derived::COption_u64Z, mut invoice_expiry_delta_secs: u32) -> crate::c_types::derived::CResult_PaymentSecretNoneZ { + let mut local_min_value_msat = if min_value_msat.is_some() { Some( { min_value_msat.take() }) } else { None }; + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.create_inbound_payment_for_hash(::lightning::ln::PaymentHash(payment_hash.data), local_min_value_msat, invoice_expiry_delta_secs); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::ThirtyTwoBytes { data: o.0 } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { () /*e*/ }).into() }; + local_ret +} + +/// Legacy version of [`create_inbound_payment_for_hash`]. Use this method if you wish to share +/// serialized state with LDK node(s) running 0.0.103 and earlier. +/// +/// # Note +/// This method is deprecated and will be removed soon. +/// +/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash +#[must_use] +#[no_mangle] +pub extern "C" fn ChannelManager_create_inbound_payment_for_hash_legacy(this_arg: &ChannelManager, mut payment_hash: crate::c_types::ThirtyTwoBytes, mut min_value_msat: crate::c_types::derived::COption_u64Z, mut invoice_expiry_delta_secs: u32) -> crate::c_types::derived::CResult_PaymentSecretAPIErrorZ { let mut local_min_value_msat = if min_value_msat.is_some() { Some( { min_value_msat.take() }) } else { None }; - let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.create_inbound_payment_for_hash(::lightning::ln::PaymentHash(payment_hash.data), local_min_value_msat, invoice_expiry_delta_secs, user_payment_id); + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.create_inbound_payment_for_hash_legacy(::lightning::ln::PaymentHash(payment_hash.data), local_min_value_msat, invoice_expiry_delta_secs); + let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::ThirtyTwoBytes { data: o.0 } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; + local_ret +} + +/// Gets an LDK-generated payment preimage from a payment hash and payment secret that were +/// previously returned from [`create_inbound_payment`]. +/// +/// [`create_inbound_payment`]: Self::create_inbound_payment +#[must_use] +#[no_mangle] +pub extern "C" fn ChannelManager_get_payment_preimage(this_arg: &ChannelManager, mut payment_hash: crate::c_types::ThirtyTwoBytes, mut payment_secret: crate::c_types::ThirtyTwoBytes) -> crate::c_types::derived::CResult_PaymentPreimageAPIErrorZ { + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.get_payment_preimage(::lightning::ln::PaymentHash(payment_hash.data), ::lightning::ln::PaymentSecret(payment_secret.data)); let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::c_types::ThirtyTwoBytes { data: o.0 } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_ret } @@ -1664,7 +1691,7 @@ impl From for crate::lightning::util::events::MessageSendE let mut rust_obj = ChannelManager { inner: ObjOps::heap_alloc(obj), is_owned: true }; let mut ret = ChannelManager_as_MessageSendEventsProvider(&rust_obj); // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn - rust_obj.inner = std::ptr::null_mut(); + rust_obj.inner = core::ptr::null_mut(); ret.free = Some(ChannelManager_free_void); ret } @@ -1692,7 +1719,7 @@ impl From for crate::lightning::util::events::EventsProvid let mut rust_obj = ChannelManager { inner: ObjOps::heap_alloc(obj), is_owned: true }; let mut ret = ChannelManager_as_EventsProvider(&rust_obj); // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn - rust_obj.inner = std::ptr::null_mut(); + rust_obj.inner = core::ptr::null_mut(); ret.free = Some(ChannelManager_free_void); ret } @@ -1717,7 +1744,7 @@ impl From for crate::lightning::chain::Listen { let mut rust_obj = ChannelManager { inner: ObjOps::heap_alloc(obj), is_owned: true }; let mut ret = ChannelManager_as_Listen(&rust_obj); // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn - rust_obj.inner = std::ptr::null_mut(); + rust_obj.inner = core::ptr::null_mut(); ret.free = Some(ChannelManager_free_void); ret } @@ -1746,7 +1773,7 @@ impl From for crate::lightning::chain::Confirm { let mut rust_obj = ChannelManager { inner: ObjOps::heap_alloc(obj), is_owned: true }; let mut ret = ChannelManager_as_Confirm(&rust_obj); // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn - rust_obj.inner = std::ptr::null_mut(); + rust_obj.inner = core::ptr::null_mut(); ret.free = Some(ChannelManager_free_void); ret } @@ -1786,11 +1813,12 @@ extern "C" fn ChannelManager_Confirm_transaction_unconfirmed(this_arg: *const c_ /// indicating whether persistence is necessary. Only one listener on /// `await_persistable_update` or `await_persistable_update_timeout` is guaranteed to be woken /// up. -/// Note that the feature `allow_wallclock_use` must be enabled to use this function. +/// +/// Note that this method is not available with the `no-std` feature. #[must_use] #[no_mangle] pub extern "C" fn ChannelManager_await_persistable_update_timeout(this_arg: &ChannelManager, mut max_wait: u64) -> bool { - let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.await_persistable_update_timeout(std::time::Duration::from_secs(max_wait)); + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.await_persistable_update_timeout(core::time::Duration::from_secs(max_wait)); ret } @@ -1816,7 +1844,7 @@ impl From for crate::lightning::ln::msgs::ChannelMessageHa let mut rust_obj = ChannelManager { inner: ObjOps::heap_alloc(obj), is_owned: true }; let mut ret = ChannelManager_as_ChannelMessageHandler(&rust_obj); // We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn - rust_obj.inner = std::ptr::null_mut(); + rust_obj.inner = core::ptr::null_mut(); ret.free = Some(ChannelManager_free_void); ret } @@ -1928,26 +1956,31 @@ pub(crate) extern "C" fn ChannelManager_write_void(obj: *const c_void) -> crate: } use lightning::ln::channelmanager::ChannelManagerReadArgs as nativeChannelManagerReadArgsImport; -type nativeChannelManagerReadArgs = nativeChannelManagerReadArgsImport<'static, crate::lightning::chain::keysinterface::Sign, crate::lightning::chain::Watch, crate::lightning::chain::chaininterface::BroadcasterInterface, crate::lightning::chain::keysinterface::KeysInterface, crate::lightning::chain::chaininterface::FeeEstimator, crate::lightning::util::logger::Logger>; +pub(crate) type nativeChannelManagerReadArgs = nativeChannelManagerReadArgsImport<'static, crate::lightning::chain::keysinterface::Sign, crate::lightning::chain::Watch, crate::lightning::chain::chaininterface::BroadcasterInterface, crate::lightning::chain::keysinterface::KeysInterface, crate::lightning::chain::chaininterface::FeeEstimator, crate::lightning::util::logger::Logger>; /// Arguments for the creation of a ChannelManager that are not deserialized. /// /// At a high-level, the process for deserializing a ChannelManager and resuming normal operation /// is: -/// 1) Deserialize all stored ChannelMonitors. -/// 2) Deserialize the ChannelManager by filling in this struct and calling: -/// <(BlockHash, ChannelManager)>::read(reader, args) -/// This may result in closing some Channels if the ChannelMonitor is newer than the stored -/// ChannelManager state to ensure no loss of funds. Thus, transactions may be broadcasted. -/// 3) If you are not fetching full blocks, register all relevant ChannelMonitor outpoints the same -/// way you would handle a `chain::Filter` call using ChannelMonitor::get_outputs_to_watch() and -/// ChannelMonitor::get_funding_txo(). -/// 4) Reconnect blocks on your ChannelMonitors. -/// 5) Disconnect/connect blocks on the ChannelManager. -/// 6) Move the ChannelMonitors into your local chain::Watch. -/// -/// Note that the ordering of #4-6 is not of importance, however all three must occur before you -/// call any other methods on the newly-deserialized ChannelManager. +/// 1) Deserialize all stored [`ChannelMonitor`]s. +/// 2) Deserialize the [`ChannelManager`] by filling in this struct and calling: +/// `<(BlockHash, ChannelManager)>::read(reader, args)` +/// This may result in closing some channels if the [`ChannelMonitor`] is newer than the stored +/// [`ChannelManager`] state to ensure no loss of funds. Thus, transactions may be broadcasted. +/// 3) If you are not fetching full blocks, register all relevant [`ChannelMonitor`] outpoints the +/// same way you would handle a [`chain::Filter`] call using +/// [`ChannelMonitor::get_outputs_to_watch`] and [`ChannelMonitor::get_funding_txo`]. +/// 4) Reconnect blocks on your [`ChannelMonitor`]s. +/// 5) Disconnect/connect blocks on the [`ChannelManager`]. +/// 6) Re-persist the [`ChannelMonitor`]s to ensure the latest state is on disk. +/// Note that if you're using a [`ChainMonitor`] for your [`chain::Watch`] implementation, you +/// will likely accomplish this as a side-effect of calling [`chain::Watch::watch_channel`] in +/// the next step. +/// 7) Move the [`ChannelMonitor`]s into your local [`chain::Watch`]. If you're using a +/// [`ChainMonitor`], this is done by calling [`chain::Watch::watch_channel`]. +/// +/// Note that the ordering of #4-7 is not of importance, however all four must occur before you +/// call any other methods on the newly-deserialized [`ChannelManager`]. /// /// Note that because some channels may be closed during deserialization, it is critical that you /// always deserialize only the latest version of a ChannelManager and ChannelMonitors available to @@ -1955,6 +1988,8 @@ type nativeChannelManagerReadArgs = nativeChannelManagerReadArgsImport<'static, /// broadcast), and then later deserialize a newer version of the same ChannelManager (which will /// not force-close the same channels but consider them live), you may end up revoking a state for /// which you've already broadcasted the transaction. +/// +/// [`ChainMonitor`]: crate::chain::chainmonitor::ChainMonitor #[must_use] #[repr(C)] pub struct ChannelManagerReadArgs { @@ -1982,7 +2017,7 @@ impl Drop for ChannelManagerReadArgs { pub extern "C" fn ChannelManagerReadArgs_free(this_obj: ChannelManagerReadArgs) { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn ChannelManagerReadArgs_free_void(this_ptr: *mut c_void) { +pub(crate) extern "C" fn ChannelManagerReadArgs_free_void(this_ptr: *mut c_void) { unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelManagerReadArgs); } } #[allow(unused)] @@ -1997,7 +2032,7 @@ impl ChannelManagerReadArgs { pub(crate) fn take_inner(mut self) -> *mut nativeChannelManagerReadArgs { assert!(self.is_owned); let ret = ObjOps::untweak_ptr(self.inner); - self.inner = std::ptr::null_mut(); + self.inner = core::ptr::null_mut(); ret } } @@ -2083,7 +2118,7 @@ pub extern "C" fn ChannelManagerReadArgs_set_logger(this_ptr: &mut ChannelManage #[no_mangle] pub extern "C" fn ChannelManagerReadArgs_get_default_config(this_ptr: &ChannelManagerReadArgs) -> crate::lightning::util::config::UserConfig { let mut inner_val = &mut this_ptr.get_native_mut_ref().default_config; - crate::lightning::util::config::UserConfig { inner: unsafe { ObjOps::nonnull_ptr_to_inner((inner_val as *const _) as *mut _) }, is_owned: false } + crate::lightning::util::config::UserConfig { inner: unsafe { ObjOps::nonnull_ptr_to_inner((inner_val as *const lightning::util::config::UserConfig<>) as *mut _) }, is_owned: false } } /// Default settings used for new channels. Any existing channels will continue to use the /// runtime settings which were stored when the ChannelManager was serialized.