X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-c-bindings%2Fsrc%2Flightning%2Fln%2Fchannelmanager.rs;h=62b675e076969162474168a514915172da21496f;hb=033f4f3b2750dcd5afc8b158d7474242b29b24f3;hp=90952e787557458c1ee1ad6f5a3b5bbbb91cadf2;hpb=2d97d367136737b0a3bcda1312354aa37f9f215c;p=ldk-c-bindings diff --git a/lightning-c-bindings/src/lightning/ln/channelmanager.rs b/lightning-c-bindings/src/lightning/ln/channelmanager.rs index 90952e7..62b675e 100644 --- a/lightning-c-bindings/src/lightning/ln/channelmanager.rs +++ b/lightning-c-bindings/src/lightning/ln/channelmanager.rs @@ -17,6 +17,7 @@ //! imply it needs to fail HTLCs/payments/channels it manages). //! +use std::str::FromStr; use std::ffi::c_void; use bitcoin::hashes::Hash; use crate::c_types::*; @@ -165,39 +166,83 @@ pub extern "C" fn ChainParameters_set_network(this_ptr: &mut ChainParameters, mu /// /// Used to track on-chain channel funding outputs and send payments with reliable timelocks. #[no_mangle] -pub extern "C" fn ChainParameters_get_best_block(this_ptr: &ChainParameters) -> crate::lightning::ln::channelmanager::BestBlock { +pub extern "C" fn ChainParameters_get_best_block(this_ptr: &ChainParameters) -> crate::lightning::chain::BestBlock { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.best_block; - crate::lightning::ln::channelmanager::BestBlock { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false } + crate::lightning::chain::BestBlock { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false } } /// The hash and height of the latest block successfully connected. /// /// Used to track on-chain channel funding outputs and send payments with reliable timelocks. #[no_mangle] -pub extern "C" fn ChainParameters_set_best_block(this_ptr: &mut ChainParameters, mut val: crate::lightning::ln::channelmanager::BestBlock) { +pub extern "C" fn ChainParameters_set_best_block(this_ptr: &mut ChainParameters, mut val: crate::lightning::chain::BestBlock) { unsafe { &mut *this_ptr.inner }.best_block = *unsafe { Box::from_raw(val.take_inner()) }; } /// Constructs a new ChainParameters given each field #[must_use] #[no_mangle] -pub extern "C" fn ChainParameters_new(mut network_arg: crate::bitcoin::network::Network, mut best_block_arg: crate::lightning::ln::channelmanager::BestBlock) -> ChainParameters { +pub extern "C" fn ChainParameters_new(mut network_arg: crate::bitcoin::network::Network, mut best_block_arg: crate::lightning::chain::BestBlock) -> ChainParameters { ChainParameters { inner: Box::into_raw(Box::new(nativeChainParameters { network: network_arg.into_bitcoin(), best_block: *unsafe { Box::from_raw(best_block_arg.take_inner()) }, })), is_owned: true } } +impl Clone for ChainParameters { + fn clone(&self) -> Self { + Self { + inner: if <*mut nativeChainParameters>::is_null(self.inner) { std::ptr::null_mut() } else { + Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) }, + is_owned: true, + } + } +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn ChainParameters_clone_void(this_ptr: *const c_void) -> *mut c_void { + Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChainParameters)).clone() })) as *mut c_void +} +#[no_mangle] +/// Creates a copy of the ChainParameters +pub extern "C" fn ChainParameters_clone(orig: &ChainParameters) -> ChainParameters { + orig.clone() +} +/// The amount of time in blocks we require our counterparty wait to claim their money (ie time +/// between when we, or our watchtower, must check for them having broadcast a theft transaction). +/// +/// This can be increased (but not decreased) through [`ChannelHandshakeConfig::our_to_self_delay`] +/// +/// [`ChannelHandshakeConfig::our_to_self_delay`]: crate::util::config::ChannelHandshakeConfig::our_to_self_delay + +#[no_mangle] +pub static BREAKDOWN_TIMEOUT: u16 = lightning::ln::channelmanager::BREAKDOWN_TIMEOUT; +/// The minimum number of blocks between an inbound HTLC's CLTV and the corresponding outbound +/// HTLC's CLTV. The current default represents roughly seven hours of blocks at six blocks/hour. +/// +/// This can be increased (but not decreased) through [`ChannelConfig::cltv_expiry_delta`] +/// +/// [`ChannelConfig::cltv_expiry_delta`]: crate::util::config::ChannelConfig::cltv_expiry_delta -use lightning::ln::channelmanager::BestBlock as nativeBestBlockImport; -type nativeBestBlock = nativeBestBlockImport; +#[no_mangle] +pub static MIN_CLTV_EXPIRY_DELTA: u16 = lightning::ln::channelmanager::MIN_CLTV_EXPIRY_DELTA; +/// Minimum CLTV difference between the current block height and received inbound payments. +/// Invoices generated for payment to us must set their `min_final_cltv_expiry` field to at least +/// this value. + +#[no_mangle] +pub static MIN_FINAL_CLTV_EXPIRY: u32 = lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY; -/// The best known block as identified by its hash and height. +use lightning::ln::channelmanager::ChannelCounterparty as nativeChannelCounterpartyImport; +type nativeChannelCounterparty = nativeChannelCounterpartyImport; + +/// Channel parameters which apply to our counterparty. These are split out from [`ChannelDetails`] +/// to better separate parameters. #[must_use] #[repr(C)] -pub struct BestBlock { +pub struct ChannelCounterparty { /// A pointer to the opaque Rust object. /// Nearly everywhere, inner must be non-null, however in places where /// the Rust equivalent takes an Option, it may be set to null to indicate None. - pub inner: *mut nativeBestBlock, + pub inner: *mut nativeChannelCounterparty, /// Indicates that this is the only struct which contains the same pointer. /// Rust functions which take ownership of an object provided via an argument require @@ -205,100 +250,99 @@ pub struct BestBlock { pub is_owned: bool, } -impl Drop for BestBlock { +impl Drop for ChannelCounterparty { fn drop(&mut self) { - if self.is_owned && !<*mut nativeBestBlock>::is_null(self.inner) { + if self.is_owned && !<*mut nativeChannelCounterparty>::is_null(self.inner) { let _ = unsafe { Box::from_raw(self.inner) }; } } } -/// Frees any resources used by the BestBlock, if is_owned is set and inner is non-NULL. +/// Frees any resources used by the ChannelCounterparty, if is_owned is set and inner is non-NULL. #[no_mangle] -pub extern "C" fn BestBlock_free(this_obj: BestBlock) { } +pub extern "C" fn ChannelCounterparty_free(this_obj: ChannelCounterparty) { } #[allow(unused)] /// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn BestBlock_free_void(this_ptr: *mut c_void) { - unsafe { let _ = Box::from_raw(this_ptr as *mut nativeBestBlock); } +extern "C" fn ChannelCounterparty_free_void(this_ptr: *mut c_void) { + unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelCounterparty); } } #[allow(unused)] /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy -impl BestBlock { - pub(crate) fn take_inner(mut self) -> *mut nativeBestBlock { +impl ChannelCounterparty { + pub(crate) fn take_inner(mut self) -> *mut nativeChannelCounterparty { assert!(self.is_owned); let ret = self.inner; self.inner = std::ptr::null_mut(); ret } } -impl Clone for BestBlock { - fn clone(&self) -> Self { - Self { - inner: if <*mut nativeBestBlock>::is_null(self.inner) { std::ptr::null_mut() } else { - Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) }, - is_owned: true, - } - } -} -#[allow(unused)] -/// Used only if an object of this type is returned as a trait impl by a method -pub(crate) extern "C" fn BestBlock_clone_void(this_ptr: *const c_void) -> *mut c_void { - Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeBestBlock)).clone() })) as *mut c_void -} -#[no_mangle] -/// Creates a copy of the BestBlock -pub extern "C" fn BestBlock_clone(orig: &BestBlock) -> BestBlock { - orig.clone() -} -/// Returns the best block from the genesis of the given network. -#[must_use] +/// The node_id of our counterparty #[no_mangle] -pub extern "C" fn BestBlock_from_genesis(mut network: crate::bitcoin::network::Network) -> BestBlock { - let mut ret = lightning::ln::channelmanager::BestBlock::from_genesis(network.into_bitcoin()); - BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true } +pub extern "C" fn ChannelCounterparty_get_node_id(this_ptr: &ChannelCounterparty) -> crate::c_types::PublicKey { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.node_id; + crate::c_types::PublicKey::from_rust(&inner_val) } - -/// Returns the best block as identified by the given block hash and height. -#[must_use] +/// The node_id of our counterparty #[no_mangle] -pub extern "C" fn BestBlock_new(mut block_hash: crate::c_types::ThirtyTwoBytes, mut height: u32) -> BestBlock { - let mut ret = lightning::ln::channelmanager::BestBlock::new(::bitcoin::hash_types::BlockHash::from_slice(&block_hash.data[..]).unwrap(), height); - BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true } +pub extern "C" fn ChannelCounterparty_set_node_id(this_ptr: &mut ChannelCounterparty, mut val: crate::c_types::PublicKey) { + unsafe { &mut *this_ptr.inner }.node_id = val.into_rust(); } - -/// Returns the best block hash. -#[must_use] +/// The Features the channel counterparty provided upon last connection. +/// Useful for routing as it is the most up-to-date copy of the counterparty's features and +/// many routing-relevant features are present in the init context. #[no_mangle] -pub extern "C" fn BestBlock_block_hash(this_arg: &BestBlock) -> crate::c_types::ThirtyTwoBytes { - let mut ret = unsafe { &*this_arg.inner }.block_hash(); - crate::c_types::ThirtyTwoBytes { data: ret.into_inner() } +pub extern "C" fn ChannelCounterparty_get_features(this_ptr: &ChannelCounterparty) -> crate::lightning::ln::features::InitFeatures { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.features; + crate::lightning::ln::features::InitFeatures { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false } } - -/// Returns the best block height. -#[must_use] +/// The Features the channel counterparty provided upon last connection. +/// Useful for routing as it is the most up-to-date copy of the counterparty's features and +/// many routing-relevant features are present in the init context. #[no_mangle] -pub extern "C" fn BestBlock_height(this_arg: &BestBlock) -> u32 { - let mut ret = unsafe { &*this_arg.inner }.height(); - ret +pub extern "C" fn ChannelCounterparty_set_features(this_ptr: &mut ChannelCounterparty, mut val: crate::lightning::ln::features::InitFeatures) { + unsafe { &mut *this_ptr.inner }.features = *unsafe { Box::from_raw(val.take_inner()) }; } - -/// The amount of time in blocks we require our counterparty wait to claim their money (ie time -/// between when we, or our watchtower, must check for them having broadcast a theft transaction). +/// The value, in satoshis, that must always be held in the channel for our counterparty. This +/// value ensures that if our counterparty broadcasts a revoked state, we can punish them by +/// claiming at least this value on chain. /// -/// This can be increased (but not decreased) through [`ChannelHandshakeConfig::our_to_self_delay`] +/// This value is not included in [`inbound_capacity_msat`] as it can never be spent. /// -/// [`ChannelHandshakeConfig::our_to_self_delay`]: crate::util::config::ChannelHandshakeConfig::our_to_self_delay - +/// [`inbound_capacity_msat`]: ChannelDetails::inbound_capacity_msat #[no_mangle] -pub static BREAKDOWN_TIMEOUT: u16 = lightning::ln::channelmanager::BREAKDOWN_TIMEOUT; -/// The minimum number of blocks between an inbound HTLC's CLTV and the corresponding outbound -/// HTLC's CLTV. The current default represents roughly six hours of blocks at six blocks/hour. +pub extern "C" fn ChannelCounterparty_get_unspendable_punishment_reserve(this_ptr: &ChannelCounterparty) -> u64 { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.unspendable_punishment_reserve; + *inner_val +} +/// The value, in satoshis, that must always be held in the channel for our counterparty. This +/// value ensures that if our counterparty broadcasts a revoked state, we can punish them by +/// claiming at least this value on chain. /// -/// This can be increased (but not decreased) through [`ChannelConfig::cltv_expiry_delta`] +/// This value is not included in [`inbound_capacity_msat`] as it can never be spent. /// -/// [`ChannelConfig::cltv_expiry_delta`]: crate::util::config::ChannelConfig::cltv_expiry_delta - +/// [`inbound_capacity_msat`]: ChannelDetails::inbound_capacity_msat #[no_mangle] -pub static MIN_CLTV_EXPIRY_DELTA: u16 = lightning::ln::channelmanager::MIN_CLTV_EXPIRY_DELTA; +pub extern "C" fn ChannelCounterparty_set_unspendable_punishment_reserve(this_ptr: &mut ChannelCounterparty, mut val: u64) { + unsafe { &mut *this_ptr.inner }.unspendable_punishment_reserve = val; +} +impl Clone for ChannelCounterparty { + fn clone(&self) -> Self { + Self { + inner: if <*mut nativeChannelCounterparty>::is_null(self.inner) { std::ptr::null_mut() } else { + Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) }, + is_owned: true, + } + } +} +#[allow(unused)] +/// Used only if an object of this type is returned as a trait impl by a method +pub(crate) extern "C" fn ChannelCounterparty_clone_void(this_ptr: *const c_void) -> *mut c_void { + Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelCounterparty)).clone() })) as *mut c_void +} +#[no_mangle] +/// Creates a copy of the ChannelCounterparty +pub extern "C" fn ChannelCounterparty_clone(orig: &ChannelCounterparty) -> ChannelCounterparty { + orig.clone() +} use lightning::ln::channelmanager::ChannelDetails as nativeChannelDetailsImport; type nativeChannelDetails = nativeChannelDetailsImport; @@ -361,6 +405,38 @@ pub extern "C" fn ChannelDetails_get_channel_id(this_ptr: &ChannelDetails) -> *c pub extern "C" fn ChannelDetails_set_channel_id(this_ptr: &mut ChannelDetails, mut val: crate::c_types::ThirtyTwoBytes) { unsafe { &mut *this_ptr.inner }.channel_id = val.data; } +/// Parameters which apply to our counterparty. See individual fields for more information. +#[no_mangle] +pub extern "C" fn ChannelDetails_get_counterparty(this_ptr: &ChannelDetails) -> crate::lightning::ln::channelmanager::ChannelCounterparty { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.counterparty; + crate::lightning::ln::channelmanager::ChannelCounterparty { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false } +} +/// Parameters which apply to our counterparty. See individual fields for more information. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_counterparty(this_ptr: &mut ChannelDetails, mut val: crate::lightning::ln::channelmanager::ChannelCounterparty) { + unsafe { &mut *this_ptr.inner }.counterparty = *unsafe { Box::from_raw(val.take_inner()) }; +} +/// The Channel's funding transaction output, if we've negotiated the funding transaction with +/// our counterparty already. +/// +/// Note that, if this has been set, `channel_id` will be equivalent to +/// `funding_txo.unwrap().to_channel_id()`. +#[no_mangle] +pub extern "C" fn ChannelDetails_get_funding_txo(this_ptr: &ChannelDetails) -> crate::lightning::chain::transaction::OutPoint { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.funding_txo; + let mut local_inner_val = crate::lightning::chain::transaction::OutPoint { inner: unsafe { (if inner_val.is_none() { std::ptr::null() } else { { (inner_val.as_ref().unwrap()) } } as *const _) as *mut _ }, is_owned: false }; + local_inner_val +} +/// The Channel's funding transaction output, if we've negotiated the funding transaction with +/// our counterparty already. +/// +/// Note that, if this has been set, `channel_id` will be equivalent to +/// `funding_txo.unwrap().to_channel_id()`. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_funding_txo(this_ptr: &mut ChannelDetails, mut val: crate::lightning::chain::transaction::OutPoint) { + let mut local_val = if val.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(val.take_inner()) } }) }; + unsafe { &mut *this_ptr.inner }.funding_txo = local_val; +} /// The position of the funding transaction in the chain. None if the funding transaction has /// not yet been confirmed and the channel fully opened. #[no_mangle] @@ -376,32 +452,6 @@ pub extern "C" fn ChannelDetails_set_short_channel_id(this_ptr: &mut ChannelDeta let mut local_val = if val.is_some() { Some( { val.take() }) } else { None }; unsafe { &mut *this_ptr.inner }.short_channel_id = local_val; } -/// The node_id of our counterparty -#[no_mangle] -pub extern "C" fn ChannelDetails_get_remote_network_id(this_ptr: &ChannelDetails) -> crate::c_types::PublicKey { - let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.remote_network_id; - crate::c_types::PublicKey::from_rust(&inner_val) -} -/// The node_id of our counterparty -#[no_mangle] -pub extern "C" fn ChannelDetails_set_remote_network_id(this_ptr: &mut ChannelDetails, mut val: crate::c_types::PublicKey) { - unsafe { &mut *this_ptr.inner }.remote_network_id = val.into_rust(); -} -/// The Features the channel counterparty provided upon last connection. -/// Useful for routing as it is the most up-to-date copy of the counterparty's features and -/// many routing-relevant features are present in the init context. -#[no_mangle] -pub extern "C" fn ChannelDetails_get_counterparty_features(this_ptr: &ChannelDetails) -> crate::lightning::ln::features::InitFeatures { - let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.counterparty_features; - crate::lightning::ln::features::InitFeatures { inner: unsafe { ( (&(*inner_val) as *const _) as *mut _) }, is_owned: false } -} -/// The Features the channel counterparty provided upon last connection. -/// Useful for routing as it is the most up-to-date copy of the counterparty's features and -/// many routing-relevant features are present in the init context. -#[no_mangle] -pub extern "C" fn ChannelDetails_set_counterparty_features(this_ptr: &mut ChannelDetails, mut val: crate::lightning::ln::features::InitFeatures) { - unsafe { &mut *this_ptr.inner }.counterparty_features = *unsafe { Box::from_raw(val.take_inner()) }; -} /// The value, in satoshis, of this channel as appears in the funding output #[no_mangle] pub extern "C" fn ChannelDetails_get_channel_value_satoshis(this_ptr: &ChannelDetails) -> u64 { @@ -413,6 +463,35 @@ pub extern "C" fn ChannelDetails_get_channel_value_satoshis(this_ptr: &ChannelDe pub extern "C" fn ChannelDetails_set_channel_value_satoshis(this_ptr: &mut ChannelDetails, mut val: u64) { unsafe { &mut *this_ptr.inner }.channel_value_satoshis = val; } +/// The value, in satoshis, that must always be held in the channel for us. This value ensures +/// that if we broadcast a revoked state, our counterparty can punish us by claiming at least +/// this value on chain. +/// +/// This value is not included in [`outbound_capacity_msat`] as it can never be spent. +/// +/// This value will be `None` for outbound channels until the counterparty accepts the channel. +/// +/// [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat +#[no_mangle] +pub extern "C" fn ChannelDetails_get_unspendable_punishment_reserve(this_ptr: &ChannelDetails) -> crate::c_types::derived::COption_u64Z { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.unspendable_punishment_reserve; + let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_u64Z::None } else { { crate::c_types::derived::COption_u64Z::Some(inner_val.unwrap()) } }; + local_inner_val +} +/// The value, in satoshis, that must always be held in the channel for us. This value ensures +/// that if we broadcast a revoked state, our counterparty can punish us by claiming at least +/// this value on chain. +/// +/// This value is not included in [`outbound_capacity_msat`] as it can never be spent. +/// +/// This value will be `None` for outbound channels until the counterparty accepts the channel. +/// +/// [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat +#[no_mangle] +pub extern "C" fn ChannelDetails_set_unspendable_punishment_reserve(this_ptr: &mut ChannelDetails, mut val: crate::c_types::derived::COption_u64Z) { + let mut local_val = if val.is_some() { Some( { val.take() }) } else { None }; + unsafe { &mut *this_ptr.inner }.unspendable_punishment_reserve = local_val; +} /// The user_id passed in to create_channel, or 0 if the channel was inbound. #[no_mangle] pub extern "C" fn ChannelDetails_get_user_id(this_ptr: &ChannelDetails) -> u64 { @@ -428,6 +507,10 @@ pub extern "C" fn ChannelDetails_set_user_id(this_ptr: &mut ChannelDetails, mut /// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not /// available for inclusion in new outbound HTLCs). This further does not include any pending /// outgoing HTLCs which are awaiting some other resolution to be sent. +/// +/// This value is not exact. Due to various in-flight changes, feerate changes, and our +/// conflict-avoidance policy, exactly this amount is not likely to be spendable. However, we +/// should be able to spend nearly this amount. #[no_mangle] pub extern "C" fn ChannelDetails_get_outbound_capacity_msat(this_ptr: &ChannelDetails) -> u64 { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.outbound_capacity_msat; @@ -437,6 +520,10 @@ pub extern "C" fn ChannelDetails_get_outbound_capacity_msat(this_ptr: &ChannelDe /// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not /// available for inclusion in new outbound HTLCs). This further does not include any pending /// outgoing HTLCs which are awaiting some other resolution to be sent. +/// +/// This value is not exact. Due to various in-flight changes, feerate changes, and our +/// conflict-avoidance policy, exactly this amount is not likely to be spendable. However, we +/// should be able to spend nearly this amount. #[no_mangle] pub extern "C" fn ChannelDetails_set_outbound_capacity_msat(this_ptr: &mut ChannelDetails, mut val: u64) { unsafe { &mut *this_ptr.inner }.outbound_capacity_msat = val; @@ -446,6 +533,10 @@ pub extern "C" fn ChannelDetails_set_outbound_capacity_msat(this_ptr: &mut Chann /// available for inclusion in new inbound HTLCs). /// Note that there are some corner cases not fully handled here, so the actual available /// inbound capacity may be slightly higher than this. +/// +/// This value is not exact. Due to various in-flight changes, feerate changes, and our +/// counterparty's conflict-avoidance policy, exactly this amount is not likely to be spendable. +/// However, our counterparty should be able to spend nearly this amount. #[no_mangle] pub extern "C" fn ChannelDetails_get_inbound_capacity_msat(this_ptr: &ChannelDetails) -> u64 { let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.inbound_capacity_msat; @@ -456,22 +547,160 @@ pub extern "C" fn ChannelDetails_get_inbound_capacity_msat(this_ptr: &ChannelDet /// available for inclusion in new inbound HTLCs). /// Note that there are some corner cases not fully handled here, so the actual available /// inbound capacity may be slightly higher than this. +/// +/// This value is not exact. Due to various in-flight changes, feerate changes, and our +/// counterparty's conflict-avoidance policy, exactly this amount is not likely to be spendable. +/// However, our counterparty should be able to spend nearly this amount. #[no_mangle] pub extern "C" fn ChannelDetails_set_inbound_capacity_msat(this_ptr: &mut ChannelDetails, mut val: u64) { unsafe { &mut *this_ptr.inner }.inbound_capacity_msat = val; } +/// The number of required confirmations on the funding transaction before the funding will be +/// considered \"locked\". This number is selected by the channel fundee (i.e. us if +/// [`is_outbound`] is *not* set), and can be selected for inbound channels with +/// [`ChannelHandshakeConfig::minimum_depth`] or limited for outbound channels with +/// [`ChannelHandshakeLimits::max_minimum_depth`]. +/// +/// This value will be `None` for outbound channels until the counterparty accepts the channel. +/// +/// [`is_outbound`]: ChannelDetails::is_outbound +/// [`ChannelHandshakeConfig::minimum_depth`]: crate::util::config::ChannelHandshakeConfig::minimum_depth +/// [`ChannelHandshakeLimits::max_minimum_depth`]: crate::util::config::ChannelHandshakeLimits::max_minimum_depth +#[no_mangle] +pub extern "C" fn ChannelDetails_get_confirmations_required(this_ptr: &ChannelDetails) -> crate::c_types::derived::COption_u32Z { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.confirmations_required; + let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_u32Z::None } else { { crate::c_types::derived::COption_u32Z::Some(inner_val.unwrap()) } }; + local_inner_val +} +/// The number of required confirmations on the funding transaction before the funding will be +/// considered \"locked\". This number is selected by the channel fundee (i.e. us if +/// [`is_outbound`] is *not* set), and can be selected for inbound channels with +/// [`ChannelHandshakeConfig::minimum_depth`] or limited for outbound channels with +/// [`ChannelHandshakeLimits::max_minimum_depth`]. +/// +/// This value will be `None` for outbound channels until the counterparty accepts the channel. +/// +/// [`is_outbound`]: ChannelDetails::is_outbound +/// [`ChannelHandshakeConfig::minimum_depth`]: crate::util::config::ChannelHandshakeConfig::minimum_depth +/// [`ChannelHandshakeLimits::max_minimum_depth`]: crate::util::config::ChannelHandshakeLimits::max_minimum_depth +#[no_mangle] +pub extern "C" fn ChannelDetails_set_confirmations_required(this_ptr: &mut ChannelDetails, mut val: crate::c_types::derived::COption_u32Z) { + let mut local_val = if val.is_some() { Some( { val.take() }) } else { None }; + unsafe { &mut *this_ptr.inner }.confirmations_required = local_val; +} +/// The number of blocks (after our commitment transaction confirms) that we will need to wait +/// until we can claim our funds after we force-close the channel. During this time our +/// counterparty is allowed to punish us if we broadcasted a stale state. If our counterparty +/// force-closes the channel and broadcasts a commitment transaction we do not have to wait any +/// time to claim our non-HTLC-encumbered funds. +/// +/// This value will be `None` for outbound channels until the counterparty accepts the channel. +#[no_mangle] +pub extern "C" fn ChannelDetails_get_force_close_spend_delay(this_ptr: &ChannelDetails) -> crate::c_types::derived::COption_u16Z { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.force_close_spend_delay; + let mut local_inner_val = if inner_val.is_none() { crate::c_types::derived::COption_u16Z::None } else { { crate::c_types::derived::COption_u16Z::Some(inner_val.unwrap()) } }; + local_inner_val +} +/// The number of blocks (after our commitment transaction confirms) that we will need to wait +/// until we can claim our funds after we force-close the channel. During this time our +/// counterparty is allowed to punish us if we broadcasted a stale state. If our counterparty +/// force-closes the channel and broadcasts a commitment transaction we do not have to wait any +/// time to claim our non-HTLC-encumbered funds. +/// +/// This value will be `None` for outbound channels until the counterparty accepts the channel. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_force_close_spend_delay(this_ptr: &mut ChannelDetails, mut val: crate::c_types::derived::COption_u16Z) { + let mut local_val = if val.is_some() { Some( { val.take() }) } else { None }; + unsafe { &mut *this_ptr.inner }.force_close_spend_delay = local_val; +} +/// True if the channel was initiated (and thus funded) by us. +#[no_mangle] +pub extern "C" fn ChannelDetails_get_is_outbound(this_ptr: &ChannelDetails) -> bool { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_outbound; + *inner_val +} +/// True if the channel was initiated (and thus funded) by us. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_is_outbound(this_ptr: &mut ChannelDetails, mut val: bool) { + unsafe { &mut *this_ptr.inner }.is_outbound = val; +} +/// True if the channel is confirmed, funding_locked messages have been exchanged, and the +/// channel is not currently being shut down. `funding_locked` message exchange implies the +/// required confirmation count has been reached (and we were connected to the peer at some +/// point after the funding transaction received enough confirmations). The required +/// confirmation count is provided in [`confirmations_required`]. +/// +/// [`confirmations_required`]: ChannelDetails::confirmations_required +#[no_mangle] +pub extern "C" fn ChannelDetails_get_is_funding_locked(this_ptr: &ChannelDetails) -> bool { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_funding_locked; + *inner_val +} +/// True if the channel is confirmed, funding_locked messages have been exchanged, and the +/// channel is not currently being shut down. `funding_locked` message exchange implies the +/// required confirmation count has been reached (and we were connected to the peer at some +/// point after the funding transaction received enough confirmations). The required +/// confirmation count is provided in [`confirmations_required`]. +/// +/// [`confirmations_required`]: ChannelDetails::confirmations_required +#[no_mangle] +pub extern "C" fn ChannelDetails_set_is_funding_locked(this_ptr: &mut ChannelDetails, mut val: bool) { + unsafe { &mut *this_ptr.inner }.is_funding_locked = val; +} /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b) -/// the peer is connected, and (c) no monitor update failure is pending resolution. +/// the peer is connected, and (c) the channel is not currently negotiating a shutdown. +/// +/// This is a strict superset of `is_funding_locked`. #[no_mangle] -pub extern "C" fn ChannelDetails_get_is_live(this_ptr: &ChannelDetails) -> bool { - let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_live; +pub extern "C" fn ChannelDetails_get_is_usable(this_ptr: &ChannelDetails) -> bool { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_usable; *inner_val } /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b) -/// the peer is connected, and (c) no monitor update failure is pending resolution. +/// the peer is connected, and (c) the channel is not currently negotiating a shutdown. +/// +/// This is a strict superset of `is_funding_locked`. +#[no_mangle] +pub extern "C" fn ChannelDetails_set_is_usable(this_ptr: &mut ChannelDetails, mut val: bool) { + unsafe { &mut *this_ptr.inner }.is_usable = val; +} +/// True if this channel is (or will be) publicly-announced. +#[no_mangle] +pub extern "C" fn ChannelDetails_get_is_public(this_ptr: &ChannelDetails) -> bool { + let mut inner_val = &mut unsafe { &mut *this_ptr.inner }.is_public; + *inner_val +} +/// True if this channel is (or will be) publicly-announced. #[no_mangle] -pub extern "C" fn ChannelDetails_set_is_live(this_ptr: &mut ChannelDetails, mut val: bool) { - unsafe { &mut *this_ptr.inner }.is_live = val; +pub extern "C" fn ChannelDetails_set_is_public(this_ptr: &mut ChannelDetails, mut val: bool) { + unsafe { &mut *this_ptr.inner }.is_public = val; +} +/// Constructs a new ChannelDetails given each field +#[must_use] +#[no_mangle] +pub extern "C" fn ChannelDetails_new(mut channel_id_arg: crate::c_types::ThirtyTwoBytes, mut counterparty_arg: crate::lightning::ln::channelmanager::ChannelCounterparty, mut funding_txo_arg: crate::lightning::chain::transaction::OutPoint, mut short_channel_id_arg: crate::c_types::derived::COption_u64Z, mut channel_value_satoshis_arg: u64, mut unspendable_punishment_reserve_arg: crate::c_types::derived::COption_u64Z, mut user_id_arg: u64, mut outbound_capacity_msat_arg: u64, mut inbound_capacity_msat_arg: u64, mut confirmations_required_arg: crate::c_types::derived::COption_u32Z, mut force_close_spend_delay_arg: crate::c_types::derived::COption_u16Z, mut is_outbound_arg: bool, mut is_funding_locked_arg: bool, mut is_usable_arg: bool, mut is_public_arg: bool) -> ChannelDetails { + let mut local_funding_txo_arg = if funding_txo_arg.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(funding_txo_arg.take_inner()) } }) }; + let mut local_short_channel_id_arg = if short_channel_id_arg.is_some() { Some( { short_channel_id_arg.take() }) } else { None }; + let mut local_unspendable_punishment_reserve_arg = if unspendable_punishment_reserve_arg.is_some() { Some( { unspendable_punishment_reserve_arg.take() }) } else { None }; + let mut local_confirmations_required_arg = if confirmations_required_arg.is_some() { Some( { confirmations_required_arg.take() }) } else { None }; + let mut local_force_close_spend_delay_arg = if force_close_spend_delay_arg.is_some() { Some( { force_close_spend_delay_arg.take() }) } else { None }; + ChannelDetails { inner: Box::into_raw(Box::new(nativeChannelDetails { + channel_id: channel_id_arg.data, + counterparty: *unsafe { Box::from_raw(counterparty_arg.take_inner()) }, + funding_txo: local_funding_txo_arg, + short_channel_id: local_short_channel_id_arg, + channel_value_satoshis: channel_value_satoshis_arg, + unspendable_punishment_reserve: local_unspendable_punishment_reserve_arg, + user_id: user_id_arg, + outbound_capacity_msat: outbound_capacity_msat_arg, + inbound_capacity_msat: inbound_capacity_msat_arg, + confirmations_required: local_confirmations_required_arg, + force_close_spend_delay: local_force_close_spend_delay_arg, + is_outbound: is_outbound_arg, + is_funding_locked: is_funding_locked_arg, + is_usable: is_usable_arg, + is_public: is_public_arg, + })), is_owned: true } } impl Clone for ChannelDetails { fn clone(&self) -> Self { @@ -602,7 +831,7 @@ impl PaymentSendFailure { }, nativePaymentSendFailure::PathParameterError (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( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_a_nonref_0 }); }; + 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::PathParameterError ( local_a_nonref.into(), ) @@ -616,7 +845,7 @@ impl PaymentSendFailure { }, 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( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_a_nonref_0 }); }; + 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(), ) @@ -632,7 +861,7 @@ impl PaymentSendFailure { ) }, nativePaymentSendFailure::PathParameterError (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( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_a_0 }); }; + 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::PathParameterError ( local_a.into(), ) @@ -644,7 +873,7 @@ impl PaymentSendFailure { ) }, 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( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; local_a_0 }); }; + 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(), ) @@ -700,12 +929,16 @@ pub extern "C" fn ChannelManager_get_current_default_configuration(this_arg: &Ch /// /// Raises APIError::APIMisuseError when channel_value_satoshis > 2**24 or push_msat is /// greater than channel_value_satoshis * 1k or channel_value_satoshis is < 1000. +/// +/// Note that we do not check if you are currently connected to the given peer. If no +/// connection is available, the outbound `open_channel` message may fail to send, resulting in +/// the channel eventually being silently forgotten. #[must_use] #[no_mangle] pub extern "C" fn ChannelManager_create_channel(this_arg: &ChannelManager, mut their_network_key: crate::c_types::PublicKey, mut channel_value_satoshis: u64, mut push_msat: u64, mut user_id: u64, mut override_config: crate::lightning::util::config::UserConfig) -> crate::c_types::derived::CResult_NoneAPIErrorZ { let mut local_override_config = if override_config.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(override_config.take_inner()) } }) }; let mut ret = unsafe { &*this_arg.inner }.create_channel(their_network_key.into_rust(), channel_value_satoshis, push_msat, user_id, local_override_config); - let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; + 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::util::errors::APIError::native_into(e) }).into() }; local_ret } @@ -722,8 +955,9 @@ pub extern "C" fn ChannelManager_list_channels(this_arg: &ChannelManager) -> cra /// Gets the list of usable channels, in random order. Useful as an argument to /// get_route to ensure non-announced channels are used. /// -/// These are guaranteed to have their is_live value set to true, see the documentation for -/// ChannelDetails::is_live for more info on exactly what the criteria are. +/// These are guaranteed to have their [`ChannelDetails::is_usable`] value set to true, see the +/// documentation for [`ChannelDetails::is_usable`] for more info on exactly what the criteria +/// are. #[must_use] #[no_mangle] pub extern "C" fn ChannelManager_list_usable_channels(this_arg: &ChannelManager) -> crate::c_types::derived::CVec_ChannelDetailsZ { @@ -741,7 +975,7 @@ pub extern "C" fn ChannelManager_list_usable_channels(this_arg: &ChannelManager) #[no_mangle] pub extern "C" fn ChannelManager_close_channel(this_arg: &ChannelManager, channel_id: *const [u8; 32]) -> crate::c_types::derived::CResult_NoneAPIErrorZ { let mut ret = unsafe { &*this_arg.inner }.close_channel(unsafe { &*channel_id}); - let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; + 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::util::errors::APIError::native_into(e) }).into() }; local_ret } @@ -751,7 +985,7 @@ pub extern "C" fn ChannelManager_close_channel(this_arg: &ChannelManager, channe #[no_mangle] pub extern "C" fn ChannelManager_force_close_channel(this_arg: &ChannelManager, channel_id: *const [u8; 32]) -> crate::c_types::derived::CResult_NoneAPIErrorZ { let mut ret = unsafe { &*this_arg.inner }.force_close_channel(unsafe { &*channel_id}); - let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; + 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::util::errors::APIError::native_into(e) }).into() }; local_ret } @@ -804,9 +1038,9 @@ pub extern "C" fn ChannelManager_force_close_all_channels(this_arg: &ChannelMana #[must_use] #[no_mangle] 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_NonePaymentSendFailureZ { - let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret.data) }) }; - let mut ret = unsafe { &*this_arg.inner }.send_payment(unsafe { &*route.inner }, ::lightning::ln::channelmanager::PaymentHash(payment_hash.data), &local_payment_secret); - let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::ln::channelmanager::PaymentSendFailure::native_into(e) }).into() }; + let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::PaymentSecret(payment_secret.data) }) }; + let mut ret = unsafe { &*this_arg.inner }.send_payment(unsafe { &*route.inner }, ::lightning::ln::PaymentHash(payment_hash.data), &local_payment_secret); + 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 } @@ -828,27 +1062,34 @@ pub extern "C" fn ChannelManager_send_payment(this_arg: &ChannelManager, route: /// Note that this includes RBF or similar transaction replacement strategies - lightning does /// not currently support replacing a funding transaction on an existing channel. Instead, /// create a new channel with a conflicting funding transaction. +/// +/// [`Event::FundingGenerationReady`]: crate::util::events::Event::FundingGenerationReady #[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 { let mut ret = unsafe { &*this_arg.inner }.funding_transaction_generated(unsafe { &*temporary_channel_id}, funding_transaction.into_bitcoin()); - let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning::util::errors::APIError::native_into(e) }).into() }; + 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::util::errors::APIError::native_into(e) }).into() }; local_ret } -/// Generates a signed node_announcement from the given arguments and creates a -/// BroadcastNodeAnnouncement event. Note that such messages will be ignored unless peers have -/// seen a channel_announcement from us (ie unless we have public channels open). +/// Regenerates channel_announcements and generates a signed node_announcement from the given +/// arguments, providing them in corresponding events via +/// [`get_and_clear_pending_msg_events`], if at least one public channel has been confirmed +/// on-chain. This effectively re-broadcasts all channel announcements and sends our node +/// announcement to ensure that the lightning P2P network is aware of the channels we have and +/// our network addresses. +/// +/// `rgb` is a node \"color\" and `alias` is a printable human-readable string to describe this +/// node to humans. They carry no in-protocol meaning. /// -/// RGB is a node \"color\" and alias is a printable human-readable string to describe this node -/// to humans. They carry no in-protocol meaning. +/// `addresses` represent the set (possibly empty) of socket addresses on which this node +/// accepts incoming connections. These will be included in the node_announcement, publicly +/// tying these addresses together and to this node. If you wish to preserve user privacy, +/// addresses should likely contain only Tor Onion addresses. /// -/// addresses represent the set (possibly empty) of socket addresses on which this node accepts -/// incoming connections. These will be broadcast to the network, publicly tying these -/// addresses together. If you wish to preserve user privacy, addresses should likely contain -/// only Tor Onion addresses. +/// Panics if `addresses` is absurdly large (more than 500). /// -/// Panics if addresses is absurdly large (more than 500). +/// [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events #[no_mangle] pub extern "C" fn ChannelManager_broadcast_node_announcement(this_arg: &ChannelManager, mut rgb: crate::c_types::ThreeBytes, mut alias: crate::c_types::ThirtyTwoBytes, mut addresses: crate::c_types::derived::CVec_NetAddressZ) { let mut local_addresses = Vec::new(); for mut item in addresses.into_rust().drain(..) { local_addresses.push( { item.into_native() }); }; @@ -883,9 +1124,8 @@ pub extern "C" fn ChannelManager_timer_tick_occurred(this_arg: &ChannelManager) /// HTLC backwards has been started. #[must_use] #[no_mangle] -pub extern "C" fn ChannelManager_fail_htlc_backwards(this_arg: &ChannelManager, payment_hash: *const [u8; 32], mut payment_secret: crate::c_types::ThirtyTwoBytes) -> bool { - let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret.data) }) }; - let mut ret = unsafe { &*this_arg.inner }.fail_htlc_backwards(&::lightning::ln::channelmanager::PaymentHash(unsafe { *payment_hash }), &local_payment_secret); +pub extern "C" fn ChannelManager_fail_htlc_backwards(this_arg: &ChannelManager, payment_hash: *const [u8; 32]) -> bool { + let mut ret = unsafe { &*this_arg.inner }.fail_htlc_backwards(&::lightning::ln::PaymentHash(unsafe { *payment_hash })); ret } @@ -893,22 +1133,19 @@ pub extern "C" fn ChannelManager_fail_htlc_backwards(this_arg: &ChannelManager, /// generating message events for the net layer to claim the payment, if possible. Thus, you /// should probably kick the net layer to go send messages if this returns true! /// -/// You must specify the expected amounts for this HTLC, and we will only claim HTLCs -/// available within a few percent of the expected amount. This is critical for several -/// reasons : a) it avoids providing senders with `proof-of-payment` (in the form of the -/// payment_preimage without having provided the full value and b) it avoids certain -/// privacy-breaking recipient-probing attacks which may reveal payment activity to -/// motivated attackers. -/// -/// Note that the privacy concerns in (b) are not relevant in payments with a payment_secret -/// set. Thus, for such payments we will claim any payments which do not under-pay. +/// 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. +/// +/// [`create_inbound_payment`]: Self::create_inbound_payment +/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash #[must_use] #[no_mangle] -pub extern "C" fn ChannelManager_claim_funds(this_arg: &ChannelManager, mut payment_preimage: crate::c_types::ThirtyTwoBytes, mut payment_secret: crate::c_types::ThirtyTwoBytes, mut expected_amount: u64) -> bool { - let mut local_payment_secret = if payment_secret.data == [0; 32] { None } else { Some( { ::lightning::ln::channelmanager::PaymentSecret(payment_secret.data) }) }; - let mut ret = unsafe { &*this_arg.inner }.claim_funds(::lightning::ln::channelmanager::PaymentPreimage(payment_preimage.data), &local_payment_secret, expected_amount); +pub extern "C" fn ChannelManager_claim_funds(this_arg: &ChannelManager, mut payment_preimage: crate::c_types::ThirtyTwoBytes) -> bool { + let mut ret = unsafe { &*this_arg.inner }.claim_funds(::lightning::ln::PaymentPreimage(payment_preimage.data)); ret } @@ -945,6 +1182,85 @@ pub extern "C" fn ChannelManager_channel_monitor_updated(this_arg: &ChannelManag unsafe { &*this_arg.inner }.channel_monitor_updated(unsafe { &*funding_txo.inner }, 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. +/// +/// 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 +/// passed directly to [`claim_funds`]. +/// +/// See [`create_inbound_payment_for_hash`] for detailed documentation on behavior and requirements. +/// +/// [`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 { + let mut local_min_value_msat = if min_value_msat.is_some() { Some( { min_value_msat.take() }) } else { None }; + let mut ret = unsafe { &*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(); + local_ret +} + +/// Gets a [`PaymentSecret`] for a given [`PaymentHash`], for which the payment preimage is +/// stored external to LDK. +/// +/// A [`PaymentReceived`] event will only be generated if the [`PaymentSecret`] matches a +/// 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 [`PaymentReceived::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. +/// +/// `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` +/// before a [`PaymentReceived`] event will be generated, ensuring that we do not provide the +/// sender \"proof-of-payment\" unless they have paid the required amount. +/// +/// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for +/// in excess of the current time. This should roughly match the expiry time set in the invoice. +/// After this many seconds, we will remove the inbound payment, resulting in any attempts to +/// pay the invoice failing. The BOLT spec suggests 3,600 secs as a default validity time for +/// invoices when no timeout is set. +/// +/// Note that we use block header time to time-out pending inbound payments (with some margin +/// to compensate for the inaccuracy of block header timestamps). Thus, in practice we will +/// accept a payment and generate a [`PaymentReceived`] event for some time after the expiry. +/// 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`]. +/// +/// [`create_inbound_payment`]: Self::create_inbound_payment +/// [`PaymentReceived`]: events::Event::PaymentReceived +/// [`PaymentReceived::user_payment_id`]: events::Event::PaymentReceived::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 { + let mut local_min_value_msat = if min_value_msat.is_some() { Some( { min_value_msat.take() }) } else { None }; + let mut ret = unsafe { &*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 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 +} + impl From for crate::lightning::util::events::MessageSendEventsProvider { fn from(obj: nativeChannelManager) -> Self { let mut rust_obj = ChannelManager { inner: Box::into_raw(Box::new(obj)), is_owned: true }; @@ -990,15 +1306,12 @@ pub extern "C" fn ChannelManager_as_EventsProvider(this_arg: &ChannelManager) -> crate::lightning::util::events::EventsProvider { this_arg: unsafe { (*this_arg).inner as *mut c_void }, free: None, - get_and_clear_pending_events: ChannelManager_EventsProvider_get_and_clear_pending_events, + process_pending_events: ChannelManager_EventsProvider_process_pending_events, } } -#[must_use] -extern "C" fn ChannelManager_EventsProvider_get_and_clear_pending_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_EventZ { - let mut ret = >::get_and_clear_pending_events(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, ); - let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::lightning::util::events::Event::native_into(item) }); }; - local_ret.into() +extern "C" fn ChannelManager_EventsProvider_process_pending_events(this_arg: *const c_void, mut handler: crate::lightning::util::events::EventHandler) { + >::process_pending_events(unsafe { &mut *(this_arg as *mut nativeChannelManager) }, handler) } impl From for crate::lightning::chain::Listen { @@ -1091,6 +1404,15 @@ pub extern "C" fn ChannelManager_await_persistable_update(this_arg: &ChannelMana unsafe { &*this_arg.inner }.await_persistable_update() } +/// Gets the latest best block which was connected either via the [`chain::Listen`] or +/// [`chain::Confirm`] interfaces. +#[must_use] +#[no_mangle] +pub extern "C" fn ChannelManager_current_best_block(this_arg: &ChannelManager) -> crate::lightning::chain::BestBlock { + let mut ret = unsafe { &*this_arg.inner }.current_best_block(); + crate::lightning::chain::BestBlock { inner: Box::into_raw(Box::new(ret)), is_owned: true } +} + impl From for crate::lightning::ln::msgs::ChannelMessageHandler { fn from(obj: nativeChannelManager) -> Self { let mut rust_obj = ChannelManager { inner: Box::into_raw(Box::new(obj)), is_owned: true };