diff --git a/genbindings.sh b/genbindings.sh index d98a2e3b..ce40ec0a 100755 --- a/genbindings.sh +++ b/genbindings.sh @@ -637,8 +637,8 @@ if [ "$CLANGPP" != "" -a "$LLD" != "" ]; then MANUAL_LINK_CFLAGS="$MANUAL_LINK_CFLAGS -C link-arg=$ARG" done # rustc appears to always look for rust-objcopy, though this may be fixed by - # https://github.com/rust-lang/rust/pull/134240 in rust 1.85. - if [ "$RUSTC_MINOR_VERSION" = 84 ]; then + # https://github.com/rust-lang/rust/pull/134240 in rust 1.85 (it is not). + if [ "$RUSTC_MINOR_VERSION" -ge 84 ]; then mkdir -p objcopy-bin ln -s `which llvm-objcopy` objcopy-bin/rust-objcopy PATH="$PATH:$(pwd)/objcopy-bin" diff --git a/lightning-c-bindings/include/lightning.h b/lightning-c-bindings/include/lightning.h index 6b96dbe6..2d92e4e4 100644 --- a/lightning-c-bindings/include/lightning.h +++ b/lightning-c-bindings/include/lightning.h @@ -11611,6 +11611,10 @@ typedef struct LDKPendingHTLCRouting_LDKForward_Body { * Note that this (or a relevant inner pointer) may be NULL or all-0s to represent None */ struct LDKBlindedForward blinded; + /** + * The absolute CLTV of the inbound HTLC + */ + struct LDKCOption_u32Z incoming_cltv_expiry; } LDKPendingHTLCRouting_LDKForward_Body; typedef struct LDKPendingHTLCRouting_LDKReceive_Body { @@ -23412,7 +23416,11 @@ typedef enum LDKOutputSpendStatus_Tag { LDKOutputSpendStatus_PendingFirstConfirmation, /** * A transaction spending the output has been confirmed on-chain but will be tracked until it - * reaches [`ANTI_REORG_DELAY`] confirmations. + * reaches at least [`PRUNE_DELAY_BLOCKS`] confirmations to ensure [`Event::SpendableOutputs`] + * stemming from lingering [`ChannelMonitor`]s can safely be replayed. + * + * [`Event::SpendableOutputs`]: crate::events::Event::SpendableOutputs + * [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor */ LDKOutputSpendStatus_PendingThresholdConfirmations, /** @@ -27873,12 +27881,16 @@ extern const uint64_t MAX_SCID_TX_INDEX; extern const uint64_t MAX_SCID_VOUT_INDEX; +extern const uint32_t PRUNE_DELAY_BLOCKS; + extern const uint64_t MIN_RELAY_FEE_SAT_PER_1000_WEIGHT; extern const uint32_t FEERATE_FLOOR_SATS_PER_KW; extern const uint32_t ANTI_REORG_DELAY; +extern const uint32_t ARCHIVAL_DELAY_BLOCKS; + extern const uint16_t BREAKDOWN_TIMEOUT; extern const uint16_t MIN_CLTV_EXPIRY_DELTA; @@ -39984,10 +39996,11 @@ MUST_USE_RES struct LDKCVec_SpendableOutputDescriptorZ ChannelMonitor_get_spenda * * This function returns a tuple of two booleans, the first indicating whether the monitor is * fully resolved, and the second whether the monitor needs persistence to ensure it is - * reliably marked as resolved within 4032 blocks. + * reliably marked as resolved within [`ARCHIVAL_DELAY_BLOCKS`] blocks. * - * The first boolean is true only if [`Self::get_claimable_balances`] has been empty for at least - * 4032 blocks as an additional protection against any bugs resulting in spuriously empty balance sets. + * The first boolean is true only if [`Self::get_claimable_balances`] has been empty for at + * least [`ARCHIVAL_DELAY_BLOCKS`] blocks as an additional protection against any bugs + * resulting in spuriously empty balance sets. */ MUST_USE_RES struct LDKC2Tuple_boolboolZ ChannelMonitor_check_and_update_full_resolution_status(const struct LDKChannelMonitor *NONNULL_PTR this_arg, const struct LDKLogger *NONNULL_PTR logger); @@ -40161,7 +40174,7 @@ struct LDKPendingHTLCRouting PendingHTLCRouting_clone(const struct LDKPendingHTL /** * Utility method to constructs a new Forward-variant PendingHTLCRouting */ -struct LDKPendingHTLCRouting PendingHTLCRouting_forward(struct LDKOnionPacket onion_packet, uint64_t short_channel_id, struct LDKBlindedForward blinded); +struct LDKPendingHTLCRouting PendingHTLCRouting_forward(struct LDKOnionPacket onion_packet, uint64_t short_channel_id, struct LDKBlindedForward blinded, struct LDKCOption_u32Z incoming_cltv_expiry); /** * Utility method to constructs a new Receive-variant PendingHTLCRouting @@ -40771,6 +40784,14 @@ void ChannelManager_force_close_all_channels_broadcasting_latest_txn(const struc */ void ChannelManager_force_close_all_channels_without_broadcasting_txn(const struct LDKChannelManager *NONNULL_PTR this_arg, struct LDKStr error_message); +/** + * Sends a payment along a given route. See [`Self::send_payment`] for more info. + * + * LDK will not automatically retry this payment, though it may be manually re-sent after an + * [`Event::PaymentFailed`] is generated. + */ +MUST_USE_RES struct LDKCResult_NoneRetryableSendFailureZ ChannelManager_send_payment_with_route(const struct LDKChannelManager *NONNULL_PTR this_arg, struct LDKRoute route, struct LDKThirtyTwoBytes payment_hash, struct LDKRecipientOnionFields recipient_onion, struct LDKThirtyTwoBytes payment_id); + /** * Sends a payment to the route found using the provided [`RouteParameters`], retrying failed * payment paths based on the provided `Retry`. @@ -40798,7 +40819,8 @@ void ChannelManager_force_close_all_channels_without_broadcasting_txn(const stru * [`ChannelManager::list_recent_payments`] for more information. * * Routes are automatically found using the [`Router] provided on startup. To fix a route for a - * particular payment, match the [`PaymentId`] passed to [`Router::find_route_with_id`]. + * particular payment, use [`Self::send_payment_with_route`] or match the [`PaymentId`] passed to + * [`Router::find_route_with_id`]. * * [`Event::PaymentSent`]: events::Event::PaymentSent * [`Event::PaymentFailed`]: events::Event::PaymentFailed @@ -56126,6 +56148,11 @@ struct LDKCResult_SpendableOutputDescriptorDecodeErrorZ SpendableOutputDescripto */ MUST_USE_RES struct LDKCResult_C2Tuple_CVec_u8Zu64ZNoneZ SpendableOutputDescriptor_create_spendable_outputs_psbt(struct LDKCVec_SpendableOutputDescriptorZ descriptors, struct LDKCVec_TxOutZ outputs, struct LDKCVec_u8Z change_destination_script, uint32_t feerate_sat_per_1000_weight, struct LDKCOption_u32Z locktime); +/** + * Returns the outpoint of the spendable output. + */ +MUST_USE_RES struct LDKOutPoint SpendableOutputDescriptor_spendable_outpoint(const struct LDKSpendableOutputDescriptor *NONNULL_PTR this_arg); + /** * Frees any resources used by the ChannelDerivationParameters, if is_owned is set and inner is non-NULL. */ diff --git a/lightning-c-bindings/src/lightning/chain/channelmonitor.rs b/lightning-c-bindings/src/lightning/chain/channelmonitor.rs index 15e3d178..63bbcaf8 100644 --- a/lightning-c-bindings/src/lightning/chain/channelmonitor.rs +++ b/lightning-c-bindings/src/lightning/chain/channelmonitor.rs @@ -560,6 +560,11 @@ pub extern "C" fn HTLCUpdate_read(ser: crate::c_types::u8slice) -> crate::c_type #[no_mangle] pub static ANTI_REORG_DELAY: u32 = lightning::chain::channelmonitor::ANTI_REORG_DELAY; +/// Number of blocks we wait before assuming a [`ChannelMonitor`] to be fully resolved and +/// considering it be safely archived. + +#[no_mangle] +pub static ARCHIVAL_DELAY_BLOCKS: u32 = lightning::chain::channelmonitor::ARCHIVAL_DELAY_BLOCKS; /// Indicates whether the balance is derived from a cooperative close, a force-close /// (for holder or counterparty), or whether it is for an HTLC. #[derive(Clone)] @@ -1580,10 +1585,11 @@ pub extern "C" fn ChannelMonitor_get_spendable_outputs(this_arg: &crate::lightni /// /// This function returns a tuple of two booleans, the first indicating whether the monitor is /// fully resolved, and the second whether the monitor needs persistence to ensure it is -/// reliably marked as resolved within 4032 blocks. +/// reliably marked as resolved within [`ARCHIVAL_DELAY_BLOCKS`] blocks. /// -/// The first boolean is true only if [`Self::get_claimable_balances`] has been empty for at least -/// 4032 blocks as an additional protection against any bugs resulting in spuriously empty balance sets. +/// The first boolean is true only if [`Self::get_claimable_balances`] has been empty for at +/// least [`ARCHIVAL_DELAY_BLOCKS`] blocks as an additional protection against any bugs +/// resulting in spuriously empty balance sets. #[must_use] #[no_mangle] pub extern "C" fn ChannelMonitor_check_and_update_full_resolution_status(this_arg: &crate::lightning::chain::channelmonitor::ChannelMonitor, logger: &crate::lightning::util::logger::Logger) -> crate::c_types::derived::C2Tuple_boolboolZ { diff --git a/lightning-c-bindings/src/lightning/ln/channelmanager.rs b/lightning-c-bindings/src/lightning/ln/channelmanager.rs index 763bbf5d..7f7c8f25 100644 --- a/lightning-c-bindings/src/lightning/ln/channelmanager.rs +++ b/lightning-c-bindings/src/lightning/ln/channelmanager.rs @@ -45,6 +45,8 @@ pub enum PendingHTLCRouting { /// /// Note that this (or a relevant inner pointer) may be NULL or all-0s to represent None blinded: crate::lightning::ln::channelmanager::BlindedForward, + /// The absolute CLTV of the inbound HTLC + incoming_cltv_expiry: crate::c_types::derived::COption_u32Z, }, /// The onion indicates that this is a payment for an invoice (supposedly) generated by us. /// @@ -129,15 +131,18 @@ impl PendingHTLCRouting { #[allow(unused)] pub(crate) fn to_native(&self) -> nativePendingHTLCRouting { match self { - PendingHTLCRouting::Forward {ref onion_packet, ref short_channel_id, ref blinded, } => { + PendingHTLCRouting::Forward {ref onion_packet, ref short_channel_id, ref blinded, ref incoming_cltv_expiry, } => { let mut onion_packet_nonref = Clone::clone(onion_packet); let mut short_channel_id_nonref = Clone::clone(short_channel_id); let mut blinded_nonref = Clone::clone(blinded); let mut local_blinded_nonref = if blinded_nonref.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(blinded_nonref.take_inner()) } }) }; + let mut incoming_cltv_expiry_nonref = Clone::clone(incoming_cltv_expiry); + let mut local_incoming_cltv_expiry_nonref = if incoming_cltv_expiry_nonref.is_some() { Some( { incoming_cltv_expiry_nonref.take() }) } else { None }; nativePendingHTLCRouting::Forward { onion_packet: *unsafe { Box::from_raw(onion_packet_nonref.take_inner()) }, short_channel_id: short_channel_id_nonref, blinded: local_blinded_nonref, + incoming_cltv_expiry: local_incoming_cltv_expiry_nonref, } }, PendingHTLCRouting::Receive {ref payment_data, ref payment_metadata, ref payment_context, ref incoming_cltv_expiry, ref phantom_shared_secret, ref custom_tlvs, ref requires_blinded_error, } => { @@ -188,12 +193,14 @@ impl PendingHTLCRouting { #[allow(unused)] pub(crate) fn into_native(self) -> nativePendingHTLCRouting { match self { - PendingHTLCRouting::Forward {mut onion_packet, mut short_channel_id, mut blinded, } => { + PendingHTLCRouting::Forward {mut onion_packet, mut short_channel_id, mut blinded, mut incoming_cltv_expiry, } => { let mut local_blinded = if blinded.inner.is_null() { None } else { Some( { *unsafe { Box::from_raw(blinded.take_inner()) } }) }; + let mut local_incoming_cltv_expiry = if incoming_cltv_expiry.is_some() { Some( { incoming_cltv_expiry.take() }) } else { None }; nativePendingHTLCRouting::Forward { onion_packet: *unsafe { Box::from_raw(onion_packet.take_inner()) }, short_channel_id: short_channel_id, blinded: local_blinded, + incoming_cltv_expiry: local_incoming_cltv_expiry, } }, PendingHTLCRouting::Receive {mut payment_data, mut payment_metadata, mut payment_context, mut incoming_cltv_expiry, mut phantom_shared_secret, mut custom_tlvs, mut requires_blinded_error, } => { @@ -231,15 +238,18 @@ impl PendingHTLCRouting { pub(crate) fn from_native(native: &PendingHTLCRoutingImport) -> Self { let native = unsafe { &*(native as *const _ as *const c_void as *const nativePendingHTLCRouting) }; match native { - nativePendingHTLCRouting::Forward {ref onion_packet, ref short_channel_id, ref blinded, } => { + nativePendingHTLCRouting::Forward {ref onion_packet, ref short_channel_id, ref blinded, ref incoming_cltv_expiry, } => { let mut onion_packet_nonref = Clone::clone(onion_packet); let mut short_channel_id_nonref = Clone::clone(short_channel_id); let mut blinded_nonref = Clone::clone(blinded); let mut local_blinded_nonref = crate::lightning::ln::channelmanager::BlindedForward { inner: if blinded_nonref.is_none() { core::ptr::null_mut() } else { { ObjOps::heap_alloc((blinded_nonref.unwrap())) } }, is_owned: true }; + let mut incoming_cltv_expiry_nonref = Clone::clone(incoming_cltv_expiry); + let mut local_incoming_cltv_expiry_nonref = if incoming_cltv_expiry_nonref.is_none() { crate::c_types::derived::COption_u32Z::None } else { crate::c_types::derived::COption_u32Z::Some( { incoming_cltv_expiry_nonref.unwrap() }) }; PendingHTLCRouting::Forward { onion_packet: crate::lightning::ln::msgs::OnionPacket { inner: ObjOps::heap_alloc(onion_packet_nonref), is_owned: true }, short_channel_id: short_channel_id_nonref, blinded: local_blinded_nonref, + incoming_cltv_expiry: local_incoming_cltv_expiry_nonref, } }, nativePendingHTLCRouting::Receive {ref payment_data, ref payment_metadata, ref payment_context, ref incoming_cltv_expiry, ref phantom_shared_secret, ref custom_tlvs, ref requires_blinded_error, } => { @@ -290,12 +300,14 @@ impl PendingHTLCRouting { #[allow(unused)] pub(crate) fn native_into(native: nativePendingHTLCRouting) -> Self { match native { - nativePendingHTLCRouting::Forward {mut onion_packet, mut short_channel_id, mut blinded, } => { + nativePendingHTLCRouting::Forward {mut onion_packet, mut short_channel_id, mut blinded, mut incoming_cltv_expiry, } => { let mut local_blinded = crate::lightning::ln::channelmanager::BlindedForward { inner: if blinded.is_none() { core::ptr::null_mut() } else { { ObjOps::heap_alloc((blinded.unwrap())) } }, is_owned: true }; + let mut local_incoming_cltv_expiry = if incoming_cltv_expiry.is_none() { crate::c_types::derived::COption_u32Z::None } else { crate::c_types::derived::COption_u32Z::Some( { incoming_cltv_expiry.unwrap() }) }; PendingHTLCRouting::Forward { onion_packet: crate::lightning::ln::msgs::OnionPacket { inner: ObjOps::heap_alloc(onion_packet), is_owned: true }, short_channel_id: short_channel_id, blinded: local_blinded, + incoming_cltv_expiry: local_incoming_cltv_expiry, } }, nativePendingHTLCRouting::Receive {mut payment_data, mut payment_metadata, mut payment_context, mut incoming_cltv_expiry, mut phantom_shared_secret, mut custom_tlvs, mut requires_blinded_error, } => { @@ -350,11 +362,12 @@ pub(crate) extern "C" fn PendingHTLCRouting_free_void(this_ptr: *mut c_void) { } #[no_mangle] /// Utility method to constructs a new Forward-variant PendingHTLCRouting -pub extern "C" fn PendingHTLCRouting_forward(onion_packet: crate::lightning::ln::msgs::OnionPacket, short_channel_id: u64, blinded: crate::lightning::ln::channelmanager::BlindedForward) -> PendingHTLCRouting { +pub extern "C" fn PendingHTLCRouting_forward(onion_packet: crate::lightning::ln::msgs::OnionPacket, short_channel_id: u64, blinded: crate::lightning::ln::channelmanager::BlindedForward, incoming_cltv_expiry: crate::c_types::derived::COption_u32Z) -> PendingHTLCRouting { PendingHTLCRouting::Forward { onion_packet, short_channel_id, blinded, + incoming_cltv_expiry, } } #[no_mangle] @@ -2673,6 +2686,18 @@ pub extern "C" fn ChannelManager_force_close_all_channels_without_broadcasting_t unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.force_close_all_channels_without_broadcasting_txn(error_message.into_string()) } +/// Sends a payment along a given route. See [`Self::send_payment`] for more info. +/// +/// LDK will not automatically retry this payment, though it may be manually re-sent after an +/// [`Event::PaymentFailed`] is generated. +#[must_use] +#[no_mangle] +pub extern "C" fn ChannelManager_send_payment_with_route(this_arg: &crate::lightning::ln::channelmanager::ChannelManager, mut route: crate::lightning::routing::router::Route, mut payment_hash: crate::c_types::ThirtyTwoBytes, mut recipient_onion: crate::lightning::ln::outbound_payment::RecipientOnionFields, mut payment_id: crate::c_types::ThirtyTwoBytes) -> crate::c_types::derived::CResult_NoneRetryableSendFailureZ { + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.send_payment_with_route(*unsafe { Box::from_raw(route.take_inner()) }, ::lightning::types::payment::PaymentHash(payment_hash.data), *unsafe { Box::from_raw(recipient_onion.take_inner()) }, ::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::outbound_payment::RetryableSendFailure::native_into(e) }).into() }; + local_ret +} + /// Sends a payment to the route found using the provided [`RouteParameters`], retrying failed /// payment paths based on the provided `Retry`. /// @@ -2699,7 +2724,8 @@ pub extern "C" fn ChannelManager_force_close_all_channels_without_broadcasting_t /// [`ChannelManager::list_recent_payments`] for more information. /// /// Routes are automatically found using the [`Router] provided on startup. To fix a route for a -/// particular payment, match the [`PaymentId`] passed to [`Router::find_route_with_id`]. +/// particular payment, use [`Self::send_payment_with_route`] or match the [`PaymentId`] passed to +/// [`Router::find_route_with_id`]. /// /// [`Event::PaymentSent`]: events::Event::PaymentSent /// [`Event::PaymentFailed`]: events::Event::PaymentFailed diff --git a/lightning-c-bindings/src/lightning/sign/mod.rs b/lightning-c-bindings/src/lightning/sign/mod.rs index 00d556d8..661ea529 100644 --- a/lightning-c-bindings/src/lightning/sign/mod.rs +++ b/lightning-c-bindings/src/lightning/sign/mod.rs @@ -805,6 +805,14 @@ pub extern "C" fn SpendableOutputDescriptor_create_spendable_outputs_psbt(mut de local_ret } +/// Returns the outpoint of the spendable output. +#[must_use] +#[no_mangle] +pub extern "C" fn SpendableOutputDescriptor_spendable_outpoint(this_arg: &crate::lightning::sign::SpendableOutputDescriptor) -> crate::lightning::chain::transaction::OutPoint { + let mut ret = this_arg.to_native().spendable_outpoint(); + crate::lightning::chain::transaction::OutPoint { inner: ObjOps::heap_alloc(ret), is_owned: true } +} + use lightning::sign::ChannelDerivationParameters as nativeChannelDerivationParametersImport; pub(crate) type nativeChannelDerivationParameters = nativeChannelDerivationParametersImport; diff --git a/lightning-c-bindings/src/lightning/util/sweep.rs b/lightning-c-bindings/src/lightning/util/sweep.rs index d2dc424c..1f2adfe8 100644 --- a/lightning-c-bindings/src/lightning/util/sweep.rs +++ b/lightning-c-bindings/src/lightning/util/sweep.rs @@ -19,6 +19,10 @@ use crate::c_types::*; #[cfg(feature="no-std")] use alloc::{vec::Vec, boxed::Box}; +/// The number of blocks we wait before we prune the tracked spendable outputs. + +#[no_mangle] +pub static PRUNE_DELAY_BLOCKS: u32 = lightning::util::sweep::PRUNE_DELAY_BLOCKS; use lightning::util::sweep::TrackedSpendableOutput as nativeTrackedSpendableOutputImport; pub(crate) type nativeTrackedSpendableOutput = nativeTrackedSpendableOutputImport; @@ -211,7 +215,11 @@ pub enum OutputSpendStatus { latest_spending_tx: crate::c_types::Transaction, }, /// A transaction spending the output has been confirmed on-chain but will be tracked until it - /// reaches [`ANTI_REORG_DELAY`] confirmations. + /// reaches at least [`PRUNE_DELAY_BLOCKS`] confirmations to ensure [`Event::SpendableOutputs`] + /// stemming from lingering [`ChannelMonitor`]s can safely be replayed. + /// + /// [`Event::SpendableOutputs`]: crate::events::Event::SpendableOutputs + /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor PendingThresholdConfirmations { /// The hash of the chain tip when we first broadcast a transaction spending this output. first_broadcast_hash: crate::c_types::ThirtyTwoBytes,