From 5f0977260e79bd470915391d7002c4bc966b2af2 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Feb 2021 14:02:20 -0500 Subject: [PATCH] - bindings updates --- lightning-c-bindings/include/lightning.h | 282 +++++++++++++----- lightning-c-bindings/include/lightningpp.hpp | 30 ++ lightning-c-bindings/include/rust_types.h | 6 - lightning-c-bindings/src/c_types/derived.rs | 80 +++++ .../src/chain/chainmonitor.rs | 2 +- .../src/chain/channelmonitor.rs | 113 ++++--- .../src/chain/keysinterface.rs | 193 ++++++++---- lightning-c-bindings/src/chain/mod.rs | 2 +- lightning-c-bindings/src/ln/channelmanager.rs | 196 +++++++++--- lightning-c-bindings/src/util/events.rs | 8 +- 10 files changed, 694 insertions(+), 218 deletions(-) diff --git a/lightning-c-bindings/include/lightning.h b/lightning-c-bindings/include/lightning.h index 131e05d93..fb39ee623 100644 --- a/lightning-c-bindings/include/lightning.h +++ b/lightning-c-bindings/include/lightning.h @@ -1551,21 +1551,20 @@ typedef struct LDKCResult_NoneChannelMonitorUpdateErrZ { /** - * An event to be processed by the ChannelManager. + * Simple structure sent back by `chain::Watch` when an HTLC from a forward channel is detected on + * chain. Used to update the corresponding HTLC in the backward channel. Failing to pass the + * preimage claim backward will lead to loss of funds. + * + * [`chain::Watch`]: ../trait.Watch.html */ -typedef struct MUST_USE_STRUCT LDKMonitorEvent { +typedef struct MUST_USE_STRUCT LDKHTLCUpdate { /** * 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. */ - LDKnativeMonitorEvent *inner; + LDKnativeHTLCUpdate *inner; bool is_owned; -} LDKMonitorEvent; - -typedef struct LDKCVec_MonitorEventZ { - struct LDKMonitorEvent *data; - uintptr_t datalen; -} LDKCVec_MonitorEventZ; +} LDKHTLCUpdate; @@ -1584,8 +1583,71 @@ typedef struct MUST_USE_STRUCT LDKOutPoint { bool is_owned; } LDKOutPoint; +/** + * An event to be processed by the ChannelManager. + */ +typedef enum LDKMonitorEvent_Tag { + /** + * A monitor event containing an HTLCUpdate. + */ + LDKMonitorEvent_HTLCEvent, + /** + * A monitor event that the Channel's commitment transaction was broadcasted. + */ + LDKMonitorEvent_CommitmentTxBroadcasted, + /** + * Must be last for serialization purposes + */ + LDKMonitorEvent_Sentinel, +} LDKMonitorEvent_Tag; + +typedef struct MUST_USE_STRUCT LDKMonitorEvent { + LDKMonitorEvent_Tag tag; + union { + struct { + struct LDKHTLCUpdate htlc_event; + }; + struct { + struct LDKOutPoint commitment_tx_broadcasted; + }; + }; +} LDKMonitorEvent; + +typedef struct LDKCVec_MonitorEventZ { + struct LDKMonitorEvent *data; + uintptr_t datalen; +} LDKCVec_MonitorEventZ; + + + +/** + * Information about a spendable output to a P2WSH script. See + * SpendableOutputDescriptor::DelayedPaymentOutput for more details on how to spend this. + */ +typedef struct MUST_USE_STRUCT LDKDelayedPaymentOutputDescriptor { + /** + * 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. + */ + LDKnativeDelayedPaymentOutputDescriptor *inner; + bool is_owned; +} LDKDelayedPaymentOutputDescriptor; + +/** + * Information about a spendable output to our \"payment key\". See + * SpendableOutputDescriptor::StaticPaymentOutput for more details on how to spend this. + */ +typedef struct MUST_USE_STRUCT LDKStaticPaymentOutputDescriptor { + /** + * 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. + */ + LDKnativeStaticPaymentOutputDescriptor *inner; + bool is_owned; +} LDKStaticPaymentOutputDescriptor; + /** * When on-chain outputs are created by rust-lightning (which our counterparty is not able to * claim at any point in the future) an event is generated which you must track and be able to @@ -1593,13 +1655,78 @@ typedef struct MUST_USE_STRUCT LDKOutPoint { * outpoint describing which txid and output index is available, the full output which exists at * that txid/index, and any keys or other information required to sign. */ -typedef struct MUST_USE_STRUCT LDKSpendableOutputDescriptor { +typedef enum LDKSpendableOutputDescriptor_Tag { /** - * 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. + * An output to a script which was provided via KeysInterface directly, either from + * `get_destination_script()` or `get_shutdown_pubkey()`, thus you should already know how to + * spend it. No secret keys are provided as rust-lightning was never given any key. + * These may include outputs from a transaction punishing our counterparty or claiming an HTLC + * on-chain using the payment preimage or after it has timed out. */ - LDKnativeSpendableOutputDescriptor *inner; - bool is_owned; + LDKSpendableOutputDescriptor_StaticOutput, + /** + * An output to a P2WSH script which can be spent with a single signature after a CSV delay. + * + * The witness in the spending input should be: + * (MINIMALIF standard rule) + * + * Note that the nSequence field in the spending input must be set to to_self_delay + * (which means the transaction is not broadcastable until at least to_self_delay + * blocks after the outpoint confirms). + * + * These are generally the result of a \"revocable\" output to us, spendable only by us unless + * it is an output from an old state which we broadcast (which should never happen). + * + * To derive the delayed_payment key which is used to sign for this input, you must pass the + * holder delayed_payment_base_key (ie the private key which corresponds to the pubkey in + * ChannelKeys::pubkeys().delayed_payment_basepoint) and the provided per_commitment_point to + * chan_utils::derive_private_key. The public key can be generated without the secret key + * using chan_utils::derive_public_key and only the delayed_payment_basepoint which appears in + * ChannelKeys::pubkeys(). + * + * To derive the revocation_pubkey provided here (which is used in the witness + * script generation), you must pass the counterparty revocation_basepoint (which appears in the + * call to ChannelKeys::ready_channel) and the provided per_commitment point + * to chan_utils::derive_public_revocation_key. + * + * The witness script which is hashed and included in the output script_pubkey may be + * regenerated by passing the revocation_pubkey (derived as above), our delayed_payment pubkey + * (derived as above), and the to_self_delay contained here to + * chan_utils::get_revokeable_redeemscript. + */ + LDKSpendableOutputDescriptor_DelayedPaymentOutput, + /** + * An output to a P2WPKH, spendable exclusively by our payment key (ie the private key which + * corresponds to the public key in ChannelKeys::pubkeys().payment_point). + * The witness in the spending input, is, thus, simply: + * + * + * These are generally the result of our counterparty having broadcast the current state, + * allowing us to claim the non-HTLC-encumbered outputs immediately. + */ + LDKSpendableOutputDescriptor_StaticPaymentOutput, + /** + * Must be last for serialization purposes + */ + LDKSpendableOutputDescriptor_Sentinel, +} LDKSpendableOutputDescriptor_Tag; + +typedef struct LDKSpendableOutputDescriptor_LDKStaticOutput_Body { + struct LDKOutPoint outpoint; + struct LDKTxOut output; +} LDKSpendableOutputDescriptor_LDKStaticOutput_Body; + +typedef struct MUST_USE_STRUCT LDKSpendableOutputDescriptor { + LDKSpendableOutputDescriptor_Tag tag; + union { + LDKSpendableOutputDescriptor_LDKStaticOutput_Body static_output; + struct { + struct LDKDelayedPaymentOutputDescriptor delayed_payment_output; + }; + struct { + struct LDKStaticPaymentOutputDescriptor static_payment_output; + }; + }; } LDKSpendableOutputDescriptor; typedef struct LDKCVec_SpendableOutputDescriptorZ { @@ -1762,24 +1889,6 @@ typedef struct LDKCResult_ChannelMonitorUpdateDecodeErrorZ { bool result_ok; } LDKCResult_ChannelMonitorUpdateDecodeErrorZ; - - -/** - * Simple structure sent back by `chain::Watch` when an HTLC from a forward channel is detected on - * chain. Used to update the corresponding HTLC in the backward channel. Failing to pass the - * preimage claim backward will lead to loss of funds. - * - * [`chain::Watch`]: ../trait.Watch.html - */ -typedef struct MUST_USE_STRUCT LDKHTLCUpdate { - /** - * 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. - */ - LDKnativeHTLCUpdate *inner; - bool is_owned; -} LDKHTLCUpdate; - typedef union LDKCResult_HTLCUpdateDecodeErrorZPtr { struct LDKHTLCUpdate *result; struct LDKDecodeError *err; @@ -2186,6 +2295,16 @@ typedef struct LDKCResult_NoneAPIErrorZ { bool result_ok; } LDKCResult_NoneAPIErrorZ; +typedef struct LDKCVec_CResult_NoneAPIErrorZZ { + struct LDKCResult_NoneAPIErrorZ *data; + uintptr_t datalen; +} LDKCVec_CResult_NoneAPIErrorZZ; + +typedef struct LDKCVec_APIErrorZ { + struct LDKAPIError *data; + uintptr_t datalen; +} LDKCVec_APIErrorZ; + /** @@ -2205,20 +2324,71 @@ typedef struct LDKCVec_ChannelDetailsZ { uintptr_t datalen; } LDKCVec_ChannelDetailsZ; - - /** * If a payment fails to send, it can be in one of several states. This enum is returned as the * Err() type describing which state the payment is in, see the description of individual enum * states for more. */ -typedef struct MUST_USE_STRUCT LDKPaymentSendFailure { +typedef enum LDKPaymentSendFailure_Tag { /** - * 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. + * A parameter which was passed to send_payment was invalid, preventing us from attempting to + * send the payment at all. No channel state has been changed or messages sent to peers, and + * once you've changed the parameter at error, you can freely retry the payment in full. */ - LDKnativePaymentSendFailure *inner; - bool is_owned; + LDKPaymentSendFailure_ParameterError, + /** + * A parameter in a single path which was passed to send_payment was invalid, preventing us + * from attempting to send the payment at all. No channel state has been changed or messages + * sent to peers, and once you've changed the parameter at error, you can freely retry the + * payment in full. + * + * The results here are ordered the same as the paths in the route object which was passed to + * send_payment. + */ + LDKPaymentSendFailure_PathParameterError, + /** + * All paths which were attempted failed to send, with no channel state change taking place. + * You can freely retry the payment in full (though you probably want to do so over different + * paths than the ones selected). + */ + LDKPaymentSendFailure_AllFailedRetrySafe, + /** + * Some paths which were attempted failed to send, though possibly not all. At least some + * paths have irrevocably committed to the HTLC and retrying the payment in full would result + * in over-/re-payment. + * + * The results here are ordered the same as the paths in the route object which was passed to + * send_payment, and any Errs which are not APIError::MonitorUpdateFailed can be safely + * retried (though there is currently no API with which to do so). + * + * Any entries which contain Err(APIError::MonitorUpdateFailed) or Ok(()) MUST NOT be retried + * 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. + */ + LDKPaymentSendFailure_PartialFailure, + /** + * Must be last for serialization purposes + */ + LDKPaymentSendFailure_Sentinel, +} LDKPaymentSendFailure_Tag; + +typedef struct MUST_USE_STRUCT LDKPaymentSendFailure { + LDKPaymentSendFailure_Tag tag; + union { + struct { + struct LDKAPIError parameter_error; + }; + struct { + struct LDKCVec_CResult_NoneAPIErrorZZ path_parameter_error; + }; + struct { + struct LDKCVec_APIErrorZ all_failed_retry_safe; + }; + struct { + struct LDKCVec_CResult_NoneAPIErrorZZ partial_failure; + }; + }; } LDKPaymentSendFailure; typedef union LDKCResult_NonePaymentSendFailureZPtr { @@ -3406,36 +3576,6 @@ typedef struct MUST_USE_STRUCT LDKChainMonitor { -/** - * Information about a spendable output to a P2WSH script. See - * SpendableOutputDescriptor::DelayedPaymentOutput for more details on how to spend this. - */ -typedef struct MUST_USE_STRUCT LDKDelayedPaymentOutputDescriptor { - /** - * 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. - */ - LDKnativeDelayedPaymentOutputDescriptor *inner; - bool is_owned; -} LDKDelayedPaymentOutputDescriptor; - - - -/** - * Information about a spendable output to our \"payment key\". See - * SpendableOutputDescriptor::StaticPaymentOutput for more details on how to spend this. - */ -typedef struct MUST_USE_STRUCT LDKStaticPaymentOutputDescriptor { - /** - * 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. - */ - LDKnativeStaticPaymentOutputDescriptor *inner; - bool is_owned; -} LDKStaticPaymentOutputDescriptor; - - - /** * Simple KeysInterface implementor that takes a 32-byte seed for use as a BIP 32 extended key * and derives keys from that. @@ -4144,6 +4284,10 @@ void CResult_NoneAPIErrorZ_free(struct LDKCResult_NoneAPIErrorZ _res); struct LDKCResult_NoneAPIErrorZ CResult_NoneAPIErrorZ_clone(const struct LDKCResult_NoneAPIErrorZ *NONNULL_PTR orig); +void CVec_CResult_NoneAPIErrorZZ_free(struct LDKCVec_CResult_NoneAPIErrorZZ _res); + +void CVec_APIErrorZ_free(struct LDKCVec_APIErrorZ _res); + void CVec_ChannelDetailsZ_free(struct LDKCVec_ChannelDetailsZ _res); struct LDKCResult_NonePaymentSendFailureZ CResult_NonePaymentSendFailureZ_ok(void); diff --git a/lightning-c-bindings/include/lightningpp.hpp b/lightning-c-bindings/include/lightningpp.hpp index b29e97c31..81370fd12 100644 --- a/lightning-c-bindings/include/lightningpp.hpp +++ b/lightning-c-bindings/include/lightningpp.hpp @@ -2321,6 +2321,21 @@ public: const LDKCResult_HolderCommitmentTransactionDecodeErrorZ* operator &() const { return &self; } const LDKCResult_HolderCommitmentTransactionDecodeErrorZ* operator ->() const { return &self; } }; +class CVec_CResult_NoneAPIErrorZZ { +private: + LDKCVec_CResult_NoneAPIErrorZZ self; +public: + CVec_CResult_NoneAPIErrorZZ(const CVec_CResult_NoneAPIErrorZZ&) = delete; + CVec_CResult_NoneAPIErrorZZ(CVec_CResult_NoneAPIErrorZZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_CResult_NoneAPIErrorZZ)); } + CVec_CResult_NoneAPIErrorZZ(LDKCVec_CResult_NoneAPIErrorZZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_CResult_NoneAPIErrorZZ)); } + operator LDKCVec_CResult_NoneAPIErrorZZ() && { LDKCVec_CResult_NoneAPIErrorZZ res = self; memset(&self, 0, sizeof(LDKCVec_CResult_NoneAPIErrorZZ)); return res; } + ~CVec_CResult_NoneAPIErrorZZ() { CVec_CResult_NoneAPIErrorZZ_free(self); } + CVec_CResult_NoneAPIErrorZZ& operator=(CVec_CResult_NoneAPIErrorZZ&& o) { CVec_CResult_NoneAPIErrorZZ_free(self); self = o.self; memset(&o, 0, sizeof(CVec_CResult_NoneAPIErrorZZ)); return *this; } + LDKCVec_CResult_NoneAPIErrorZZ* operator &() { return &self; } + LDKCVec_CResult_NoneAPIErrorZZ* operator ->() { return &self; } + const LDKCVec_CResult_NoneAPIErrorZZ* operator &() const { return &self; } + const LDKCVec_CResult_NoneAPIErrorZZ* operator ->() const { return &self; } +}; class CResult_SignatureNoneZ { private: LDKCResult_SignatureNoneZ self; @@ -3101,6 +3116,21 @@ public: const LDKCResult_ChannelUpdateDecodeErrorZ* operator &() const { return &self; } const LDKCResult_ChannelUpdateDecodeErrorZ* operator ->() const { return &self; } }; +class CVec_APIErrorZ { +private: + LDKCVec_APIErrorZ self; +public: + CVec_APIErrorZ(const CVec_APIErrorZ&) = delete; + CVec_APIErrorZ(CVec_APIErrorZ&& o) : self(o.self) { memset(&o, 0, sizeof(CVec_APIErrorZ)); } + CVec_APIErrorZ(LDKCVec_APIErrorZ&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKCVec_APIErrorZ)); } + operator LDKCVec_APIErrorZ() && { LDKCVec_APIErrorZ res = self; memset(&self, 0, sizeof(LDKCVec_APIErrorZ)); return res; } + ~CVec_APIErrorZ() { CVec_APIErrorZ_free(self); } + CVec_APIErrorZ& operator=(CVec_APIErrorZ&& o) { CVec_APIErrorZ_free(self); self = o.self; memset(&o, 0, sizeof(CVec_APIErrorZ)); return *this; } + LDKCVec_APIErrorZ* operator &() { return &self; } + LDKCVec_APIErrorZ* operator ->() { return &self; } + const LDKCVec_APIErrorZ* operator &() const { return &self; } + const LDKCVec_APIErrorZ* operator ->() const { return &self; } +}; class CVec_UpdateFulfillHTLCZ { private: LDKCVec_UpdateFulfillHTLCZ self; diff --git a/lightning-c-bindings/include/rust_types.h b/lightning-c-bindings/include/rust_types.h index dd72f91f3..d76b09afe 100644 --- a/lightning-c-bindings/include/rust_types.h +++ b/lightning-c-bindings/include/rust_types.h @@ -75,8 +75,6 @@ struct nativeChannelMonitorUpdateOpaque; typedef struct nativeChannelMonitorUpdateOpaque LDKnativeChannelMonitorUpdate; struct nativeMonitorUpdateErrorOpaque; typedef struct nativeMonitorUpdateErrorOpaque LDKnativeMonitorUpdateError; -struct nativeMonitorEventOpaque; -typedef struct nativeMonitorEventOpaque LDKnativeMonitorEvent; struct nativeHTLCUpdateOpaque; typedef struct nativeHTLCUpdateOpaque LDKnativeHTLCUpdate; struct nativeChannelMonitorOpaque; @@ -85,16 +83,12 @@ struct nativeChannelManagerOpaque; typedef struct nativeChannelManagerOpaque LDKnativeChannelManager; struct nativeChannelDetailsOpaque; typedef struct nativeChannelDetailsOpaque LDKnativeChannelDetails; -struct nativePaymentSendFailureOpaque; -typedef struct nativePaymentSendFailureOpaque LDKnativePaymentSendFailure; struct nativeChannelManagerReadArgsOpaque; typedef struct nativeChannelManagerReadArgsOpaque LDKnativeChannelManagerReadArgs; struct nativeDelayedPaymentOutputDescriptorOpaque; typedef struct nativeDelayedPaymentOutputDescriptorOpaque LDKnativeDelayedPaymentOutputDescriptor; struct nativeStaticPaymentOutputDescriptorOpaque; typedef struct nativeStaticPaymentOutputDescriptorOpaque LDKnativeStaticPaymentOutputDescriptor; -struct nativeSpendableOutputDescriptorOpaque; -typedef struct nativeSpendableOutputDescriptorOpaque LDKnativeSpendableOutputDescriptor; struct LDKChannelKeys; typedef struct LDKChannelKeys LDKChannelKeys; struct nativeInMemoryChannelKeysOpaque; diff --git a/lightning-c-bindings/src/c_types/derived.rs b/lightning-c-bindings/src/c_types/derived.rs index 8a8b4ecab..2ea8d6ff9 100644 --- a/lightning-c-bindings/src/c_types/derived.rs +++ b/lightning-c-bindings/src/c_types/derived.rs @@ -3286,6 +3286,86 @@ impl Clone for CResult_NoneAPIErrorZ { #[no_mangle] pub extern "C" fn CResult_NoneAPIErrorZ_clone(orig: &CResult_NoneAPIErrorZ) -> CResult_NoneAPIErrorZ { orig.clone() } #[repr(C)] +pub struct CVec_CResult_NoneAPIErrorZZ { + pub data: *mut crate::c_types::derived::CResult_NoneAPIErrorZ, + pub datalen: usize +} +impl CVec_CResult_NoneAPIErrorZZ { + #[allow(unused)] pub(crate) fn into_rust(&mut self) -> Vec { + if self.datalen == 0 { return Vec::new(); } + let ret = unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }.into(); + self.data = std::ptr::null_mut(); + self.datalen = 0; + ret + } + #[allow(unused)] pub(crate) fn as_slice(&self) -> &[crate::c_types::derived::CResult_NoneAPIErrorZ] { + unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) } + } +} +impl From> for CVec_CResult_NoneAPIErrorZZ { + fn from(v: Vec) -> Self { + let datalen = v.len(); + let data = Box::into_raw(v.into_boxed_slice()); + Self { datalen, data: unsafe { (*data).as_mut_ptr() } } + } +} +#[no_mangle] +pub extern "C" fn CVec_CResult_NoneAPIErrorZZ_free(_res: CVec_CResult_NoneAPIErrorZZ) { } +impl Drop for CVec_CResult_NoneAPIErrorZZ { + fn drop(&mut self) { + if self.datalen == 0 { return; } + unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }; + } +} +impl Clone for CVec_CResult_NoneAPIErrorZZ { + fn clone(&self) -> Self { + let mut res = Vec::new(); + if self.datalen == 0 { return Self::from(res); } + res.extend_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) }); + Self::from(res) + } +} +#[repr(C)] +pub struct CVec_APIErrorZ { + pub data: *mut crate::util::errors::APIError, + pub datalen: usize +} +impl CVec_APIErrorZ { + #[allow(unused)] pub(crate) fn into_rust(&mut self) -> Vec { + if self.datalen == 0 { return Vec::new(); } + let ret = unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }.into(); + self.data = std::ptr::null_mut(); + self.datalen = 0; + ret + } + #[allow(unused)] pub(crate) fn as_slice(&self) -> &[crate::util::errors::APIError] { + unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) } + } +} +impl From> for CVec_APIErrorZ { + fn from(v: Vec) -> Self { + let datalen = v.len(); + let data = Box::into_raw(v.into_boxed_slice()); + Self { datalen, data: unsafe { (*data).as_mut_ptr() } } + } +} +#[no_mangle] +pub extern "C" fn CVec_APIErrorZ_free(_res: CVec_APIErrorZ) { } +impl Drop for CVec_APIErrorZ { + fn drop(&mut self) { + if self.datalen == 0 { return; } + unsafe { Box::from_raw(std::slice::from_raw_parts_mut(self.data, self.datalen)) }; + } +} +impl Clone for CVec_APIErrorZ { + fn clone(&self) -> Self { + let mut res = Vec::new(); + if self.datalen == 0 { return Self::from(res); } + res.extend_from_slice(unsafe { std::slice::from_raw_parts_mut(self.data, self.datalen) }); + Self::from(res) + } +} +#[repr(C)] pub struct CVec_ChannelDetailsZ { pub data: *mut crate::ln::channelmanager::ChannelDetails, pub datalen: usize diff --git a/lightning-c-bindings/src/chain/chainmonitor.rs b/lightning-c-bindings/src/chain/chainmonitor.rs index 73061fce3..f4d5262dd 100644 --- a/lightning-c-bindings/src/chain/chainmonitor.rs +++ b/lightning-c-bindings/src/chain/chainmonitor.rs @@ -153,7 +153,7 @@ extern "C" fn ChainMonitor_Watch_update_channel(this_arg: *const c_void, mut fun #[must_use] extern "C" fn ChainMonitor_Watch_release_pending_monitor_events(this_arg: *const c_void) -> crate::c_types::derived::CVec_MonitorEventZ { let mut ret = unsafe { &mut *(this_arg as *mut nativeChainMonitor) }.release_pending_monitor_events(); - let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::chain::channelmonitor::MonitorEvent { inner: Box::into_raw(Box::new(item)), is_owned: true } }); }; + let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::chain::channelmonitor::MonitorEvent::native_into(item) }); }; local_ret.into() } diff --git a/lightning-c-bindings/src/chain/channelmonitor.rs b/lightning-c-bindings/src/chain/channelmonitor.rs index 247bd7544..f1f39e6d0 100644 --- a/lightning-c-bindings/src/chain/channelmonitor.rs +++ b/lightning-c-bindings/src/chain/channelmonitor.rs @@ -283,58 +283,85 @@ pub(crate) extern "C" fn MonitorUpdateError_clone_void(this_ptr: *const c_void) pub extern "C" fn MonitorUpdateError_clone(orig: &MonitorUpdateError) -> MonitorUpdateError { orig.clone() } - -use lightning::chain::channelmonitor::MonitorEvent as nativeMonitorEventImport; -type nativeMonitorEvent = nativeMonitorEventImport; - /// An event to be processed by the ChannelManager. #[must_use] +#[derive(Clone)] #[repr(C)] -pub struct MonitorEvent { - /// 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 nativeMonitorEvent, - pub is_owned: bool, +pub enum MonitorEvent { + /// A monitor event containing an HTLCUpdate. + HTLCEvent(crate::chain::channelmonitor::HTLCUpdate), + /// A monitor event that the Channel's commitment transaction was broadcasted. + CommitmentTxBroadcasted(crate::chain::transaction::OutPoint), } - -impl Drop for MonitorEvent { - fn drop(&mut self) { - if self.is_owned && !self.inner.is_null() { - let _ = unsafe { Box::from_raw(self.inner) }; +use lightning::chain::channelmonitor::MonitorEvent as nativeMonitorEvent; +impl MonitorEvent { + #[allow(unused)] + pub(crate) fn to_native(&self) -> nativeMonitorEvent { + match self { + MonitorEvent::HTLCEvent (ref a, ) => { + let mut a_nonref = (*a).clone(); + nativeMonitorEvent::HTLCEvent ( + *unsafe { Box::from_raw(a_nonref.take_inner()) }, + ) + }, + MonitorEvent::CommitmentTxBroadcasted (ref a, ) => { + let mut a_nonref = (*a).clone(); + nativeMonitorEvent::CommitmentTxBroadcasted ( + *unsafe { Box::from_raw(a_nonref.take_inner()) }, + ) + }, } } -} -#[no_mangle] -pub extern "C" fn MonitorEvent_free(this_ptr: MonitorEvent) { } -#[allow(unused)] -/// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn MonitorEvent_free_void(this_ptr: *mut c_void) { - unsafe { let _ = Box::from_raw(this_ptr as *mut nativeMonitorEvent); } -} -#[allow(unused)] -/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy -impl MonitorEvent { - pub(crate) fn take_inner(mut self) -> *mut nativeMonitorEvent { - assert!(self.is_owned); - let ret = self.inner; - self.inner = std::ptr::null_mut(); - ret + #[allow(unused)] + pub(crate) fn into_native(self) -> nativeMonitorEvent { + match self { + MonitorEvent::HTLCEvent (mut a, ) => { + nativeMonitorEvent::HTLCEvent ( + *unsafe { Box::from_raw(a.take_inner()) }, + ) + }, + MonitorEvent::CommitmentTxBroadcasted (mut a, ) => { + nativeMonitorEvent::CommitmentTxBroadcasted ( + *unsafe { Box::from_raw(a.take_inner()) }, + ) + }, + } } -} -impl Clone for MonitorEvent { - fn clone(&self) -> Self { - Self { - inner: if self.inner.is_null() { std::ptr::null_mut() } else { - Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) }, - is_owned: true, + #[allow(unused)] + pub(crate) fn from_native(native: &nativeMonitorEvent) -> Self { + match native { + nativeMonitorEvent::HTLCEvent (ref a, ) => { + let mut a_nonref = (*a).clone(); + MonitorEvent::HTLCEvent ( + crate::chain::channelmonitor::HTLCUpdate { inner: Box::into_raw(Box::new(a_nonref)), is_owned: true }, + ) + }, + nativeMonitorEvent::CommitmentTxBroadcasted (ref a, ) => { + let mut a_nonref = (*a).clone(); + MonitorEvent::CommitmentTxBroadcasted ( + crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(a_nonref)), is_owned: true }, + ) + }, + } + } + #[allow(unused)] + pub(crate) fn native_into(native: nativeMonitorEvent) -> Self { + match native { + nativeMonitorEvent::HTLCEvent (mut a, ) => { + MonitorEvent::HTLCEvent ( + crate::chain::channelmonitor::HTLCUpdate { inner: Box::into_raw(Box::new(a)), is_owned: true }, + ) + }, + nativeMonitorEvent::CommitmentTxBroadcasted (mut a, ) => { + MonitorEvent::CommitmentTxBroadcasted ( + crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(a)), 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 MonitorEvent_clone_void(this_ptr: *const c_void) -> *mut c_void { - Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeMonitorEvent)).clone() })) as *mut c_void -} +#[no_mangle] +pub extern "C" fn MonitorEvent_free(this_ptr: MonitorEvent) { } #[no_mangle] pub extern "C" fn MonitorEvent_clone(orig: &MonitorEvent) -> MonitorEvent { orig.clone() @@ -512,7 +539,7 @@ pub extern "C" fn ChannelMonitor_get_funding_txo(this_arg: &ChannelMonitor) -> c #[no_mangle] pub extern "C" fn ChannelMonitor_get_and_clear_pending_monitor_events(this_arg: &mut ChannelMonitor) -> crate::c_types::derived::CVec_MonitorEventZ { let mut ret = unsafe { &mut (*(this_arg.inner as *mut nativeChannelMonitor)) }.get_and_clear_pending_monitor_events(); - let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::chain::channelmonitor::MonitorEvent { inner: Box::into_raw(Box::new(item)), is_owned: true } }); }; + let mut local_ret = Vec::new(); for mut item in ret.drain(..) { local_ret.push( { crate::chain::channelmonitor::MonitorEvent::native_into(item) }); }; local_ret.into() } diff --git a/lightning-c-bindings/src/chain/keysinterface.rs b/lightning-c-bindings/src/chain/keysinterface.rs index 576a62050..7642138ed 100644 --- a/lightning-c-bindings/src/chain/keysinterface.rs +++ b/lightning-c-bindings/src/chain/keysinterface.rs @@ -264,78 +264,171 @@ pub(crate) extern "C" fn StaticPaymentOutputDescriptor_clone_void(this_ptr: *con pub extern "C" fn StaticPaymentOutputDescriptor_clone(orig: &StaticPaymentOutputDescriptor) -> StaticPaymentOutputDescriptor { orig.clone() } - -use lightning::chain::keysinterface::SpendableOutputDescriptor as nativeSpendableOutputDescriptorImport; -type nativeSpendableOutputDescriptor = nativeSpendableOutputDescriptorImport; - /// When on-chain outputs are created by rust-lightning (which our counterparty is not able to /// claim at any point in the future) an event is generated which you must track and be able to /// spend on-chain. The information needed to do this is provided in this enum, including the /// outpoint describing which txid and output index is available, the full output which exists at /// that txid/index, and any keys or other information required to sign. #[must_use] +#[derive(Clone)] #[repr(C)] -pub struct SpendableOutputDescriptor { - /// 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 nativeSpendableOutputDescriptor, - pub is_owned: bool, +pub enum SpendableOutputDescriptor { + /// An output to a script which was provided via KeysInterface directly, either from + /// `get_destination_script()` or `get_shutdown_pubkey()`, thus you should already know how to + /// spend it. No secret keys are provided as rust-lightning was never given any key. + /// These may include outputs from a transaction punishing our counterparty or claiming an HTLC + /// on-chain using the payment preimage or after it has timed out. + StaticOutput { + outpoint: crate::chain::transaction::OutPoint, + output: crate::c_types::TxOut, + }, + /// An output to a P2WSH script which can be spent with a single signature after a CSV delay. + /// + /// The witness in the spending input should be: + /// (MINIMALIF standard rule) + /// + /// Note that the nSequence field in the spending input must be set to to_self_delay + /// (which means the transaction is not broadcastable until at least to_self_delay + /// blocks after the outpoint confirms). + /// + /// These are generally the result of a \"revocable\" output to us, spendable only by us unless + /// it is an output from an old state which we broadcast (which should never happen). + /// + /// To derive the delayed_payment key which is used to sign for this input, you must pass the + /// holder delayed_payment_base_key (ie the private key which corresponds to the pubkey in + /// ChannelKeys::pubkeys().delayed_payment_basepoint) and the provided per_commitment_point to + /// chan_utils::derive_private_key. The public key can be generated without the secret key + /// using chan_utils::derive_public_key and only the delayed_payment_basepoint which appears in + /// ChannelKeys::pubkeys(). + /// + /// To derive the revocation_pubkey provided here (which is used in the witness + /// script generation), you must pass the counterparty revocation_basepoint (which appears in the + /// call to ChannelKeys::ready_channel) and the provided per_commitment point + /// to chan_utils::derive_public_revocation_key. + /// + /// The witness script which is hashed and included in the output script_pubkey may be + /// regenerated by passing the revocation_pubkey (derived as above), our delayed_payment pubkey + /// (derived as above), and the to_self_delay contained here to + /// chan_utils::get_revokeable_redeemscript. + DelayedPaymentOutput(crate::chain::keysinterface::DelayedPaymentOutputDescriptor), + /// An output to a P2WPKH, spendable exclusively by our payment key (ie the private key which + /// corresponds to the public key in ChannelKeys::pubkeys().payment_point). + /// The witness in the spending input, is, thus, simply: + /// + /// + /// These are generally the result of our counterparty having broadcast the current state, + /// allowing us to claim the non-HTLC-encumbered outputs immediately. + StaticPaymentOutput(crate::chain::keysinterface::StaticPaymentOutputDescriptor), } - -impl Drop for SpendableOutputDescriptor { - fn drop(&mut self) { - if self.is_owned && !self.inner.is_null() { - let _ = unsafe { Box::from_raw(self.inner) }; +use lightning::chain::keysinterface::SpendableOutputDescriptor as nativeSpendableOutputDescriptor; +impl SpendableOutputDescriptor { + #[allow(unused)] + pub(crate) fn to_native(&self) -> nativeSpendableOutputDescriptor { + match self { + SpendableOutputDescriptor::StaticOutput {ref outpoint, ref output, } => { + let mut outpoint_nonref = (*outpoint).clone(); + let mut output_nonref = (*output).clone(); + nativeSpendableOutputDescriptor::StaticOutput { + outpoint: *unsafe { Box::from_raw(outpoint_nonref.take_inner()) }, + output: output_nonref.into_rust(), + } + }, + SpendableOutputDescriptor::DelayedPaymentOutput (ref a, ) => { + let mut a_nonref = (*a).clone(); + nativeSpendableOutputDescriptor::DelayedPaymentOutput ( + *unsafe { Box::from_raw(a_nonref.take_inner()) }, + ) + }, + SpendableOutputDescriptor::StaticPaymentOutput (ref a, ) => { + let mut a_nonref = (*a).clone(); + nativeSpendableOutputDescriptor::StaticPaymentOutput ( + *unsafe { Box::from_raw(a_nonref.take_inner()) }, + ) + }, } } -} -#[no_mangle] -pub extern "C" fn SpendableOutputDescriptor_free(this_ptr: SpendableOutputDescriptor) { } -#[allow(unused)] -/// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn SpendableOutputDescriptor_free_void(this_ptr: *mut c_void) { - unsafe { let _ = Box::from_raw(this_ptr as *mut nativeSpendableOutputDescriptor); } -} -#[allow(unused)] -/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy -impl SpendableOutputDescriptor { - pub(crate) fn take_inner(mut self) -> *mut nativeSpendableOutputDescriptor { - assert!(self.is_owned); - let ret = self.inner; - self.inner = std::ptr::null_mut(); - ret + #[allow(unused)] + pub(crate) fn into_native(self) -> nativeSpendableOutputDescriptor { + match self { + SpendableOutputDescriptor::StaticOutput {mut outpoint, mut output, } => { + nativeSpendableOutputDescriptor::StaticOutput { + outpoint: *unsafe { Box::from_raw(outpoint.take_inner()) }, + output: output.into_rust(), + } + }, + SpendableOutputDescriptor::DelayedPaymentOutput (mut a, ) => { + nativeSpendableOutputDescriptor::DelayedPaymentOutput ( + *unsafe { Box::from_raw(a.take_inner()) }, + ) + }, + SpendableOutputDescriptor::StaticPaymentOutput (mut a, ) => { + nativeSpendableOutputDescriptor::StaticPaymentOutput ( + *unsafe { Box::from_raw(a.take_inner()) }, + ) + }, + } } -} -impl Clone for SpendableOutputDescriptor { - fn clone(&self) -> Self { - Self { - inner: if self.inner.is_null() { std::ptr::null_mut() } else { - Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) }, - is_owned: true, + #[allow(unused)] + pub(crate) fn from_native(native: &nativeSpendableOutputDescriptor) -> Self { + match native { + nativeSpendableOutputDescriptor::StaticOutput {ref outpoint, ref output, } => { + let mut outpoint_nonref = (*outpoint).clone(); + let mut output_nonref = (*output).clone(); + SpendableOutputDescriptor::StaticOutput { + outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint_nonref)), is_owned: true }, + output: crate::c_types::TxOut::from_rust(output_nonref), + } + }, + nativeSpendableOutputDescriptor::DelayedPaymentOutput (ref a, ) => { + let mut a_nonref = (*a).clone(); + SpendableOutputDescriptor::DelayedPaymentOutput ( + crate::chain::keysinterface::DelayedPaymentOutputDescriptor { inner: Box::into_raw(Box::new(a_nonref)), is_owned: true }, + ) + }, + nativeSpendableOutputDescriptor::StaticPaymentOutput (ref a, ) => { + let mut a_nonref = (*a).clone(); + SpendableOutputDescriptor::StaticPaymentOutput ( + crate::chain::keysinterface::StaticPaymentOutputDescriptor { inner: Box::into_raw(Box::new(a_nonref)), is_owned: true }, + ) + }, + } + } + #[allow(unused)] + pub(crate) fn native_into(native: nativeSpendableOutputDescriptor) -> Self { + match native { + nativeSpendableOutputDescriptor::StaticOutput {mut outpoint, mut output, } => { + SpendableOutputDescriptor::StaticOutput { + outpoint: crate::chain::transaction::OutPoint { inner: Box::into_raw(Box::new(outpoint)), is_owned: true }, + output: crate::c_types::TxOut::from_rust(output), + } + }, + nativeSpendableOutputDescriptor::DelayedPaymentOutput (mut a, ) => { + SpendableOutputDescriptor::DelayedPaymentOutput ( + crate::chain::keysinterface::DelayedPaymentOutputDescriptor { inner: Box::into_raw(Box::new(a)), is_owned: true }, + ) + }, + nativeSpendableOutputDescriptor::StaticPaymentOutput (mut a, ) => { + SpendableOutputDescriptor::StaticPaymentOutput ( + crate::chain::keysinterface::StaticPaymentOutputDescriptor { inner: Box::into_raw(Box::new(a)), 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 SpendableOutputDescriptor_clone_void(this_ptr: *const c_void) -> *mut c_void { - Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeSpendableOutputDescriptor)).clone() })) as *mut c_void } #[no_mangle] +pub extern "C" fn SpendableOutputDescriptor_free(this_ptr: SpendableOutputDescriptor) { } +#[no_mangle] pub extern "C" fn SpendableOutputDescriptor_clone(orig: &SpendableOutputDescriptor) -> SpendableOutputDescriptor { orig.clone() } #[no_mangle] pub extern "C" fn SpendableOutputDescriptor_write(obj: &SpendableOutputDescriptor) -> crate::c_types::derived::CVec_u8Z { - crate::c_types::serialize_obj(unsafe { &*unsafe { &*obj }.inner }) -} -#[no_mangle] -pub(crate) extern "C" fn SpendableOutputDescriptor_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z { - crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeSpendableOutputDescriptor) }) + crate::c_types::serialize_obj(&unsafe { &*obj }.to_native()) } #[no_mangle] pub extern "C" fn SpendableOutputDescriptor_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_SpendableOutputDescriptorDecodeErrorZ { let res = crate::c_types::deserialize_obj(ser); - let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::keysinterface::SpendableOutputDescriptor { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; + let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::keysinterface::SpendableOutputDescriptor::native_into(o) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; local_res } /// Set of lightning keys needed to operate a channel as described in BOLT 3. @@ -1109,9 +1202,9 @@ pub extern "C" fn KeysManager_derive_channel_keys(this_arg: &KeysManager, mut ch #[must_use] #[no_mangle] pub extern "C" fn KeysManager_spend_spendable_outputs(this_arg: &KeysManager, mut descriptors: crate::c_types::derived::CVec_SpendableOutputDescriptorZ, mut outputs: crate::c_types::derived::CVec_TxOutZ, mut change_destination_script: crate::c_types::derived::CVec_u8Z, mut feerate_sat_per_1000_weight: u32) -> crate::c_types::derived::CResult_TransactionNoneZ { - let mut local_descriptors = Vec::new(); for mut item in descriptors.as_slice().iter() { local_descriptors.push( { unsafe { &*item.inner } }); }; + let mut local_descriptors = Vec::new(); for mut item in descriptors.into_rust().drain(..) { local_descriptors.push( { item.into_native() }); }; let mut local_outputs = Vec::new(); for mut item in outputs.into_rust().drain(..) { local_outputs.push( { item.into_rust() }); }; - let mut ret = unsafe { &*this_arg.inner }.spend_spendable_outputs(&local_descriptors[..], local_outputs, ::bitcoin::blockdata::script::Script::from(change_destination_script.into_rust()), feerate_sat_per_1000_weight, &bitcoin::secp256k1::Secp256k1::new()); + let mut ret = unsafe { &*this_arg.inner }.spend_spendable_outputs(&local_descriptors.iter().collect::>()[..], local_outputs, ::bitcoin::blockdata::script::Script::from(change_destination_script.into_rust()), feerate_sat_per_1000_weight, &bitcoin::secp256k1::Secp256k1::new()); let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { let mut local_ret_0 = ::bitcoin::consensus::encode::serialize(&o); crate::c_types::Transaction::from_vec(local_ret_0) }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { 0u8 /*e*/ }).into() }; local_ret } diff --git a/lightning-c-bindings/src/chain/mod.rs b/lightning-c-bindings/src/chain/mod.rs index fa337d314..b7c6bd78e 100644 --- a/lightning-c-bindings/src/chain/mod.rs +++ b/lightning-c-bindings/src/chain/mod.rs @@ -168,7 +168,7 @@ impl rustWatch for Watch { } fn release_pending_monitor_events(&self) -> Vec { let mut ret = (self.release_pending_monitor_events)(self.this_arg); - let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { *unsafe { Box::from_raw(item.take_inner()) } }); }; + let mut local_ret = Vec::new(); for mut item in ret.into_rust().drain(..) { local_ret.push( { item.into_native() }); }; local_ret } } diff --git a/lightning-c-bindings/src/ln/channelmanager.rs b/lightning-c-bindings/src/ln/channelmanager.rs index d0bd90ebf..5fa3e1a9c 100644 --- a/lightning-c-bindings/src/ln/channelmanager.rs +++ b/lightning-c-bindings/src/ln/channelmanager.rs @@ -256,60 +256,168 @@ pub(crate) extern "C" fn ChannelDetails_clone_void(this_ptr: *const c_void) -> * pub extern "C" fn ChannelDetails_clone(orig: &ChannelDetails) -> ChannelDetails { orig.clone() } - -use lightning::ln::channelmanager::PaymentSendFailure as nativePaymentSendFailureImport; -type nativePaymentSendFailure = nativePaymentSendFailureImport; - /// If a payment fails to send, it can be in one of several states. This enum is returned as the /// Err() type describing which state the payment is in, see the description of individual enum /// states for more. #[must_use] +#[derive(Clone)] #[repr(C)] -pub struct PaymentSendFailure { - /// 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 nativePaymentSendFailure, - pub is_owned: bool, -} - -impl Drop for PaymentSendFailure { - fn drop(&mut self) { - if self.is_owned && !self.inner.is_null() { - let _ = unsafe { Box::from_raw(self.inner) }; +pub enum PaymentSendFailure { + /// A parameter which was passed to send_payment was invalid, preventing us from attempting to + /// send the payment at all. No channel state has been changed or messages sent to peers, and + /// once you've changed the parameter at error, you can freely retry the payment in full. + ParameterError(crate::util::errors::APIError), + /// A parameter in a single path which was passed to send_payment was invalid, preventing us + /// from attempting to send the payment at all. No channel state has been changed or messages + /// sent to peers, and once you've changed the parameter at error, you can freely retry the + /// payment in full. + /// + /// The results here are ordered the same as the paths in the route object which was passed to + /// send_payment. + PathParameterError(crate::c_types::derived::CVec_CResult_NoneAPIErrorZZ), + /// All paths which were attempted failed to send, with no channel state change taking place. + /// You can freely retry the payment in full (though you probably want to do so over different + /// paths than the ones selected). + AllFailedRetrySafe(crate::c_types::derived::CVec_APIErrorZ), + /// Some paths which were attempted failed to send, though possibly not all. At least some + /// paths have irrevocably committed to the HTLC and retrying the payment in full would result + /// in over-/re-payment. + /// + /// The results here are ordered the same as the paths in the route object which was passed to + /// send_payment, and any Errs which are not APIError::MonitorUpdateFailed can be safely + /// retried (though there is currently no API with which to do so). + /// + /// Any entries which contain Err(APIError::MonitorUpdateFailed) or Ok(()) MUST NOT be retried + /// 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), +} +use lightning::ln::channelmanager::PaymentSendFailure as nativePaymentSendFailure; +impl PaymentSendFailure { + #[allow(unused)] + pub(crate) fn to_native(&self) -> nativePaymentSendFailure { + match self { + PaymentSendFailure::ParameterError (ref a, ) => { + let mut a_nonref = (*a).clone(); + nativePaymentSendFailure::ParameterError ( + a_nonref.into_native(), + ) + }, + PaymentSendFailure::PathParameterError (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::PathParameterError ( + local_a_nonref, + ) + }, + PaymentSendFailure::AllFailedRetrySafe (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( { item.into_native() }); }; + nativePaymentSendFailure::AllFailedRetrySafe ( + 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, + ) + }, } } -} -#[no_mangle] -pub extern "C" fn PaymentSendFailure_free(this_ptr: PaymentSendFailure) { } -#[allow(unused)] -/// Used only if an object of this type is returned as a trait impl by a method -extern "C" fn PaymentSendFailure_free_void(this_ptr: *mut c_void) { - unsafe { let _ = Box::from_raw(this_ptr as *mut nativePaymentSendFailure); } -} -#[allow(unused)] -/// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy -impl PaymentSendFailure { - pub(crate) fn take_inner(mut self) -> *mut nativePaymentSendFailure { - assert!(self.is_owned); - let ret = self.inner; - self.inner = std::ptr::null_mut(); - ret + #[allow(unused)] + pub(crate) fn into_native(self) -> nativePaymentSendFailure { + match self { + PaymentSendFailure::ParameterError (mut a, ) => { + nativePaymentSendFailure::ParameterError ( + a.into_native(), + ) + }, + PaymentSendFailure::PathParameterError (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::PathParameterError ( + local_a, + ) + }, + PaymentSendFailure::AllFailedRetrySafe (mut a, ) => { + let mut local_a = Vec::new(); for mut item in a.into_rust().drain(..) { local_a.push( { item.into_native() }); }; + nativePaymentSendFailure::AllFailedRetrySafe ( + 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, + ) + }, + } } -} -impl Clone for PaymentSendFailure { - fn clone(&self) -> Self { - Self { - inner: if self.inner.is_null() { std::ptr::null_mut() } else { - Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) }, - is_owned: true, + #[allow(unused)] + pub(crate) fn from_native(native: &nativePaymentSendFailure) -> Self { + match native { + nativePaymentSendFailure::ParameterError (ref a, ) => { + let mut a_nonref = (*a).clone(); + PaymentSendFailure::ParameterError ( + crate::util::errors::APIError::native_into(a_nonref), + ) + }, + 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::util::errors::APIError::native_into(e) }).into() }; local_a_nonref_0 }); }; + PaymentSendFailure::PathParameterError ( + local_a_nonref.into(), + ) + }, + nativePaymentSendFailure::AllFailedRetrySafe (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( { crate::util::errors::APIError::native_into(item) }); }; + PaymentSendFailure::AllFailedRetrySafe ( + 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( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::util::errors::APIError::native_into(e) }).into() }; local_a_nonref_0 }); }; + PaymentSendFailure::PartialFailure ( + local_a_nonref.into(), + ) + }, + } + } + #[allow(unused)] + pub(crate) fn native_into(native: nativePaymentSendFailure) -> Self { + match native { + nativePaymentSendFailure::ParameterError (mut a, ) => { + PaymentSendFailure::ParameterError ( + crate::util::errors::APIError::native_into(a), + ) + }, + 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::util::errors::APIError::native_into(e) }).into() }; local_a_0 }); }; + PaymentSendFailure::PathParameterError ( + local_a.into(), + ) + }, + nativePaymentSendFailure::AllFailedRetrySafe (mut a, ) => { + let mut local_a = Vec::new(); for mut item in a.drain(..) { local_a.push( { crate::util::errors::APIError::native_into(item) }); }; + PaymentSendFailure::AllFailedRetrySafe ( + 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( { 0u8 /*o*/ }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::util::errors::APIError::native_into(e) }).into() }; local_a_0 }); }; + PaymentSendFailure::PartialFailure ( + local_a.into(), + ) + }, } } } -#[allow(unused)] -/// Used only if an object of this type is returned as a trait impl by a method -pub(crate) extern "C" fn PaymentSendFailure_clone_void(this_ptr: *const c_void) -> *mut c_void { - Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativePaymentSendFailure)).clone() })) as *mut c_void -} +#[no_mangle] +pub extern "C" fn PaymentSendFailure_free(this_ptr: PaymentSendFailure) { } #[no_mangle] pub extern "C" fn PaymentSendFailure_clone(orig: &PaymentSendFailure) -> PaymentSendFailure { orig.clone() @@ -453,7 +561,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::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::ln::channelmanager::PaymentSendFailure { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() }; + 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::ln::channelmanager::PaymentSendFailure::native_into(e) }).into() }; local_ret } diff --git a/lightning-c-bindings/src/util/events.rs b/lightning-c-bindings/src/util/events.rs index bf08d9c6f..52893679e 100644 --- a/lightning-c-bindings/src/util/events.rs +++ b/lightning-c-bindings/src/util/events.rs @@ -137,7 +137,7 @@ impl Event { }, Event::SpendableOutputs {ref outputs, } => { let mut outputs_nonref = (*outputs).clone(); - let mut local_outputs_nonref = Vec::new(); for mut item in outputs_nonref.into_rust().drain(..) { local_outputs_nonref.push( { *unsafe { Box::from_raw(item.take_inner()) } }); }; + let mut local_outputs_nonref = Vec::new(); for mut item in outputs_nonref.into_rust().drain(..) { local_outputs_nonref.push( { item.into_native() }); }; nativeEvent::SpendableOutputs { outputs: local_outputs_nonref, } @@ -186,7 +186,7 @@ impl Event { } }, Event::SpendableOutputs {mut outputs, } => { - let mut local_outputs = Vec::new(); for mut item in outputs.into_rust().drain(..) { local_outputs.push( { *unsafe { Box::from_raw(item.take_inner()) } }); }; + let mut local_outputs = Vec::new(); for mut item in outputs.into_rust().drain(..) { local_outputs.push( { item.into_native() }); }; nativeEvent::SpendableOutputs { outputs: local_outputs, } @@ -249,7 +249,7 @@ impl Event { }, nativeEvent::SpendableOutputs {ref outputs, } => { let mut outputs_nonref = (*outputs).clone(); - let mut local_outputs_nonref = Vec::new(); for mut item in outputs_nonref.drain(..) { local_outputs_nonref.push( { crate::chain::keysinterface::SpendableOutputDescriptor { inner: Box::into_raw(Box::new(item)), is_owned: true } }); }; + let mut local_outputs_nonref = Vec::new(); for mut item in outputs_nonref.drain(..) { local_outputs_nonref.push( { crate::chain::keysinterface::SpendableOutputDescriptor::native_into(item) }); }; Event::SpendableOutputs { outputs: local_outputs_nonref.into(), } @@ -298,7 +298,7 @@ impl Event { } }, nativeEvent::SpendableOutputs {mut outputs, } => { - let mut local_outputs = Vec::new(); for mut item in outputs.drain(..) { local_outputs.push( { crate::chain::keysinterface::SpendableOutputDescriptor { inner: Box::into_raw(Box::new(item)), is_owned: true } }); }; + let mut local_outputs = Vec::new(); for mut item in outputs.drain(..) { local_outputs.push( { crate::chain::keysinterface::SpendableOutputDescriptor::native_into(item) }); }; Event::SpendableOutputs { outputs: local_outputs.into(), } -- 2.39.5