X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fevents%2Fmod.rs;h=665fd0ed23a51ae27b7c260b33717ac9690f74db;hb=0a0c54cc3122be58a034bcd699e9df34fd734678;hp=4f3b55804c72753a8bcdaba64bb0a327547e7944;hpb=369eea45a1efadda2dc1fe6496dfdcaad0c4d1e1;p=rust-lightning diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs index 4f3b5580..665fd0ed 100644 --- a/lightning/src/events/mod.rs +++ b/lightning/src/events/mod.rs @@ -20,8 +20,8 @@ pub mod bump_transaction; #[cfg(anchors)] pub use bump_transaction::BumpTransactionEvent; -use crate::chain::keysinterface::SpendableOutputDescriptor; -use crate::ln::channelmanager::{InterceptId, PaymentId}; +use crate::sign::SpendableOutputDescriptor; +use crate::ln::channelmanager::{InterceptId, PaymentId, RecipientOnionFields}; use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS; use crate::ln::features::ChannelTypeFeatures; use crate::ln::msgs; @@ -30,9 +30,11 @@ use crate::routing::gossip::NetworkUpdate; use crate::util::errors::APIError; use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, RequiredWrapper, UpgradableRequired, WithoutLength}; use crate::util::string::UntrustedString; -use crate::routing::router::{RouteHop, RouteParameters}; +use crate::routing::router::{BlindedTail, Path, RouteHop, RouteParameters}; -use bitcoin::{PackedLockTime, Transaction}; +use bitcoin::{PackedLockTime, Transaction, OutPoint}; +#[cfg(anchors)] +use bitcoin::{Txid, TxIn, TxOut, Witness}; use bitcoin::blockdata::script::Script; use bitcoin::hashes::Hash; use bitcoin::hashes::sha256::Hash as Sha256; @@ -127,7 +129,7 @@ pub enum ClosureReason { /// Be careful about printing the peer_msg, a well-crafted message could exploit /// a security vulnerability in the terminal emulator or the logging subsystem. /// To be safe, use `Display` on `UntrustedString` - /// + /// /// [`UntrustedString`]: crate::util::string::UntrustedString peer_msg: UntrustedString, }, @@ -230,8 +232,11 @@ pub enum HTLCDestination { /// /// Some of the reasons may include: /// * HTLC Timeouts - /// * Expected MPP amount to claim does not equal HTLC total - /// * Claimable amount does not match expected amount + /// * Excess HTLCs for a payment that we have already fully received, over-paying for the + /// payment, + /// * The counterparty node modified the HTLC in transit, + /// * A probing attack where an intermediary node is trying to detect if we are the ultimate + /// recipient for a payment. FailedPayment { /// The payment hash of the payment we attempted to process. payment_hash: PaymentHash @@ -270,6 +275,43 @@ impl_writeable_tlv_based_enum!(InterceptNextHop, }; ); +/// The reason the payment failed. Used in [`Event::PaymentFailed`]. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum PaymentFailureReason { + /// The intended recipient rejected our payment. + RecipientRejected, + /// The user chose to abandon this payment by calling [`ChannelManager::abandon_payment`]. + /// + /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment + UserAbandoned, + /// We exhausted all of our retry attempts while trying to send the payment, or we + /// exhausted the [`Retry::Timeout`] if the user set one. If at any point a retry + /// attempt failed while being forwarded along the path, an [`Event::PaymentPathFailed`] will + /// have come before this. + /// + /// [`Retry::Timeout`]: crate::ln::channelmanager::Retry::Timeout + RetriesExhausted, + /// The payment expired while retrying, based on the provided + /// [`PaymentParameters::expiry_time`]. + /// + /// [`PaymentParameters::expiry_time`]: crate::routing::router::PaymentParameters::expiry_time + PaymentExpired, + /// We failed to find a route while retrying the payment. + RouteNotFound, + /// This error should generally never happen. This likely means that there is a problem with + /// your router. + UnexpectedError, +} + +impl_writeable_tlv_based_enum!(PaymentFailureReason, + (0, RecipientRejected) => {}, + (2, UserAbandoned) => {}, + (4, RetriesExhausted) => {}, + (6, PaymentExpired) => {}, + (8, RouteNotFound) => {}, + (10, UnexpectedError) => {}, ; +); + /// An Event which you should probably take some action in response to. /// /// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use @@ -319,7 +361,9 @@ pub enum Event { /// /// # Note /// LDK will not stop an inbound payment from being paid multiple times, so multiple - /// `PaymentClaimable` events may be generated for the same payment. + /// `PaymentClaimable` events may be generated for the same payment. In such a case it is + /// polite (and required in the lightning specification) to fail the payment the second time + /// and give the sender their money back rather than accepting double payment. /// /// # Note /// This event used to be called `PaymentReceived` in LDK versions 0.0.112 and earlier. @@ -333,11 +377,16 @@ pub enum Event { /// This field will always be filled in when the event was generated by LDK versions /// 0.0.113 and above. /// - /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager + /// [phantom nodes]: crate::sign::PhantomKeysManager receiver_node_id: Option, /// The hash for which the preimage should be handed to the ChannelManager. Note that LDK will /// not stop you from registering duplicate payment hashes for inbound payments. payment_hash: PaymentHash, + /// The fields in the onion which were received with each HTLC. Only fields which were + /// identical in each HTLC involved in the payment will be included here. + /// + /// Payments received on LDK versions prior to 0.0.115 will have this field unset. + onion_fields: Option, /// The value, in thousandths of a satoshi, that this payment is for. amount_msat: u64, /// Information for claiming this received payment, based on whether the purpose of the @@ -347,6 +396,14 @@ pub enum Event { via_channel_id: Option<[u8; 32]>, /// The `user_channel_id` indicating over which channel we received the payment. via_user_channel_id: Option, + /// The block height at which this payment will be failed back and will no longer be + /// eligible for claiming. + /// + /// Prior to this height, a call to [`ChannelManager::claim_funds`] is guaranteed to + /// succeed, however you should wait for [`Event::PaymentClaimed`] to be sure. + /// + /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds + claim_deadline: Option, }, /// Indicates a payment has been claimed and we've received money! /// @@ -368,7 +425,7 @@ pub enum Event { /// This field will always be filled in when the event was generated by LDK versions /// 0.0.113 and above. /// - /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager + /// [phantom nodes]: crate::sign::PhantomKeysManager receiver_node_id: Option, /// The payment hash of the claimed payment. Note that LDK will not stop you from /// registering duplicate payment hashes for inbound payments. @@ -385,7 +442,7 @@ pub enum Event { /// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentPathFailed` /// event. In this situation, you SHOULD treat this payment as having succeeded. PaymentSent { - /// The id returned by [`ChannelManager::send_payment`]. + /// The `payment_id` passed to [`ChannelManager::send_payment`]. /// /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment payment_id: Option, @@ -418,34 +475,37 @@ pub enum Event { /// [`Retry`]: crate::ln::channelmanager::Retry /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment PaymentFailed { - /// The id returned by [`ChannelManager::send_payment`] and used with - /// [`ChannelManager::abandon_payment`]. + /// The `payment_id` passed to [`ChannelManager::send_payment`]. /// /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment - /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment payment_id: PaymentId, /// The hash that was given to [`ChannelManager::send_payment`]. /// /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment payment_hash: PaymentHash, + /// The reason the payment failed. This is only `None` for events generated or serialized + /// by versions prior to 0.0.115. + reason: Option, }, /// Indicates that a path for an outbound payment was successful. /// /// Always generated after [`Event::PaymentSent`] and thus useful for scoring channels. See /// [`Event::PaymentSent`] for obtaining the payment preimage. PaymentPathSuccessful { - /// The id returned by [`ChannelManager::send_payment`]. + /// The `payment_id` passed to [`ChannelManager::send_payment`]. /// /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment payment_id: PaymentId, /// The hash that was given to [`ChannelManager::send_payment`]. /// + /// This will be `Some` for all payments which completed on LDK 0.0.104 or later. + /// /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment payment_hash: Option, /// The payment path that was successful. /// /// May contain a closed channel if the HTLC sent along the path was fulfilled on chain. - path: Vec, + path: Path, }, /// Indicates an outbound HTLC we sent failed, likely due to an intermediary node being unable to /// handle the HTLC. @@ -458,8 +518,9 @@ pub enum Event { /// /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment PaymentPathFailed { - /// The id returned by [`ChannelManager::send_payment`] and used with - /// [`ChannelManager::abandon_payment`]. + /// The `payment_id` passed to [`ChannelManager::send_payment`]. + /// + /// This will be `Some` for all payment paths which failed on LDK 0.0.103 or later. /// /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment @@ -478,7 +539,7 @@ pub enum Event { /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph failure: PathFailure, /// The payment path that failed. - path: Vec, + path: Path, /// The channel responsible for the failed payment path. /// /// Note that for route hints or for the first hop in a path this may be an SCID alias and @@ -504,7 +565,7 @@ pub enum Event { /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe payment_hash: PaymentHash, /// The payment path that was successful. - path: Vec, + path: Path, }, /// Indicates that a probe payment we sent failed at an intermediary node on the path. ProbeFailed { @@ -517,7 +578,7 @@ pub enum Event { /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe payment_hash: PaymentHash, /// The payment path that failed. - path: Vec, + path: Path, /// The channel responsible for the failed probe. /// /// Note that for route hints or for the first hop in a path this may be an SCID alias and @@ -603,13 +664,44 @@ pub enum Event { /// If this is `true`, the forwarded HTLC was claimed by our counterparty via an on-chain /// transaction. claim_from_onchain_tx: bool, + /// The final amount forwarded, in milli-satoshis, after the fee is deducted. + /// + /// The caveat described above the `fee_earned_msat` field applies here as well. + outbound_amount_forwarded_msat: Option, + }, + /// Used to indicate that a channel with the given `channel_id` is being opened and pending + /// confirmation on-chain. + /// + /// This event is emitted when the funding transaction has been signed and is broadcast to the + /// network. For 0conf channels it will be immediately followed by the corresponding + /// [`Event::ChannelReady`] event. + ChannelPending { + /// The `channel_id` of the channel that is pending confirmation. + channel_id: [u8; 32], + /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound + /// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if + /// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise + /// `user_channel_id` will be randomized for an inbound channel. + /// + /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel + /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel + /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels + user_channel_id: u128, + /// The `temporary_channel_id` this channel used to be known by during channel establishment. + /// + /// Will be `None` for channels created prior to LDK version 0.0.115. + former_temporary_channel_id: Option<[u8; 32]>, + /// The `node_id` of the channel counterparty. + counterparty_node_id: PublicKey, + /// The outpoint of the channel's funding transaction. + funding_txo: OutPoint, }, /// Used to indicate that a channel with the given `channel_id` is ready to /// be used. This event is emitted either when the funding transaction has been confirmed /// on-chain, or, in case of a 0conf channel, when both parties have confirmed the channel /// establishment. ChannelReady { - /// The channel_id of the channel that is ready. + /// The `channel_id` of the channel that is ready. channel_id: [u8; 32], /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound /// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if @@ -620,7 +712,7 @@ pub enum Event { /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels user_channel_id: u128, - /// The node_id of the channel counterparty. + /// The `node_id` of the channel counterparty. counterparty_node_id: PublicKey, /// The features that this channel will operate with. channel_type: ChannelTypeFeatures, @@ -628,7 +720,7 @@ pub enum Event { /// Used to indicate that a previously opened channel with the given `channel_id` is in the /// process of closure. ChannelClosed { - /// The channel_id of the channel which has been closed. Note that on-chain transactions + /// The `channel_id` of the channel which has been closed. Note that on-chain transactions /// resolving the channel are likely still awaiting confirmation. channel_id: [u8; 32], /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound @@ -712,7 +804,7 @@ pub enum Event { /// * Insufficient capacity in the outbound channel /// * While waiting to forward the HTLC, the channel it is meant to be forwarded through closes /// * When an unknown SCID is requested for forwarding a payment. - /// * Claiming an amount for an MPP payment that exceeds the HTLC total + /// * Expected MPP amount has already been reached /// * The HTLC has timed out /// /// This event, however, does not get generated if an HTLC fails to meet the forwarding @@ -740,7 +832,10 @@ impl Writeable for Event { // We never write out FundingGenerationReady events as, upon disconnection, peers // drop any channels which have not yet exchanged funding_signed. }, - &Event::PaymentClaimable { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id, ref via_channel_id, ref via_user_channel_id } => { + &Event::PaymentClaimable { ref payment_hash, ref amount_msat, ref purpose, + ref receiver_node_id, ref via_channel_id, ref via_user_channel_id, + ref claim_deadline, ref onion_fields + } => { 1u8.write(writer)?; let mut payment_secret = None; let payment_preimage; @@ -761,7 +856,9 @@ impl Writeable for Event { (4, amount_msat, required), (5, via_user_channel_id, option), (6, 0u64, required), // user_payment_id required for compatibility with 0.0.103 and earlier + (7, claim_deadline, option), (8, payment_preimage, option), + (9, onion_fields, option), }); }, &Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => { @@ -791,7 +888,8 @@ impl Writeable for Event { (1, None::, option), // network_update in LDK versions prior to 0.0.114 (2, payment_failed_permanently, required), (3, false, required), // all_paths_failed in LDK versions prior to 0.0.114 - (5, *path, vec_type), + (4, path.blinded_tail, option), + (5, path.hops, vec_type), (7, short_channel_id, option), (9, None::, option), // retry in LDK versions prior to 0.0.115 (11, payment_id, option), @@ -820,13 +918,17 @@ impl Writeable for Event { (8, expected_outbound_amount_msat, required), }); } - &Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => { + &Event::PaymentForwarded { + fee_earned_msat, prev_channel_id, claim_from_onchain_tx, + next_channel_id, outbound_amount_forwarded_msat + } => { 7u8.write(writer)?; write_tlv_fields!(writer, { (0, fee_earned_msat, option), (1, prev_channel_id, option), (2, claim_from_onchain_tx, required), (3, next_channel_id, option), + (5, outbound_amount_forwarded_msat, option), }); }, &Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason } => { @@ -855,13 +957,15 @@ impl Writeable for Event { write_tlv_fields!(writer, { (0, payment_id, required), (2, payment_hash, option), - (4, *path, vec_type) + (4, path.hops, vec_type), + (6, path.blinded_tail, option), }) }, - &Event::PaymentFailed { ref payment_id, ref payment_hash } => { + &Event::PaymentFailed { ref payment_id, ref payment_hash, ref reason } => { 15u8.write(writer)?; write_tlv_fields!(writer, { (0, payment_id, required), + (1, reason, option), (2, payment_hash, required), }) }, @@ -884,7 +988,8 @@ impl Writeable for Event { write_tlv_fields!(writer, { (0, payment_id, required), (2, payment_hash, required), - (4, *path, vec_type) + (4, path.hops, vec_type), + (6, path.blinded_tail, option), }) }, &Event::ProbeFailed { ref payment_id, ref payment_hash, ref path, ref short_channel_id } => { @@ -892,8 +997,9 @@ impl Writeable for Event { write_tlv_fields!(writer, { (0, payment_id, required), (2, payment_hash, required), - (4, *path, vec_type), + (4, path.hops, vec_type), (6, short_channel_id, option), + (8, path.blinded_tail, option), }) }, &Event::HTLCHandlingFailed { ref prev_channel_id, ref failed_next_destination } => { @@ -923,6 +1029,16 @@ impl Writeable for Event { (6, channel_type, required), }); }, + &Event::ChannelPending { ref channel_id, ref user_channel_id, ref former_temporary_channel_id, ref counterparty_node_id, ref funding_txo } => { + 31u8.write(writer)?; + write_tlv_fields!(writer, { + (0, channel_id, required), + (2, user_channel_id, required), + (4, former_temporary_channel_id, required), + (6, counterparty_node_id, required), + (8, funding_txo, required), + }); + }, // Note that, going forward, all new events must only write data inside of // `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write // data via `write_tlv_fields`. @@ -945,7 +1061,9 @@ impl MaybeReadable for Event { let mut receiver_node_id = None; let mut _user_payment_id = None::; // For compatibility with 0.0.103 and earlier let mut via_channel_id = None; + let mut claim_deadline = None; let mut via_user_channel_id = None; + let mut onion_fields = None; read_tlv_fields!(reader, { (0, payment_hash, required), (1, receiver_node_id, option), @@ -954,7 +1072,9 @@ impl MaybeReadable for Event { (4, amount_msat, required), (5, via_user_channel_id, option), (6, _user_payment_id, option), + (7, claim_deadline, option), (8, payment_preimage, option), + (9, onion_fields, option), }); let purpose = match payment_secret { Some(secret) => PaymentPurpose::InvoicePayment { @@ -971,6 +1091,8 @@ impl MaybeReadable for Event { purpose, via_channel_id, via_user_channel_id, + claim_deadline, + onion_fields, })) }; f() @@ -1008,6 +1130,7 @@ impl MaybeReadable for Event { let mut payment_hash = PaymentHash([0; 32]); let mut payment_failed_permanently = false; let mut network_update = None; + let mut blinded_tail: Option = None; let mut path: Option> = Some(vec![]); let mut short_channel_id = None; let mut payment_id = None; @@ -1016,6 +1139,7 @@ impl MaybeReadable for Event { (0, payment_hash, required), (1, network_update, upgradable_option), (2, payment_failed_permanently, required), + (4, blinded_tail, option), (5, path, vec_type), (7, short_channel_id, option), (11, payment_id, option), @@ -1027,7 +1151,7 @@ impl MaybeReadable for Event { payment_hash, payment_failed_permanently, failure, - path: path.unwrap(), + path: Path { hops: path.unwrap(), blinded_tail }, short_channel_id, #[cfg(test)] error_code, @@ -1078,13 +1202,18 @@ impl MaybeReadable for Event { let mut prev_channel_id = None; let mut claim_from_onchain_tx = false; let mut next_channel_id = None; + let mut outbound_amount_forwarded_msat = None; read_tlv_fields!(reader, { (0, fee_earned_msat, option), (1, prev_channel_id, option), (2, claim_from_onchain_tx, required), (3, next_channel_id, option), + (5, outbound_amount_forwarded_msat, option), }); - Ok(Some(Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id })) + Ok(Some(Event::PaymentForwarded { + fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id, + outbound_amount_forwarded_msat + })) }; f() }, @@ -1125,18 +1254,16 @@ impl MaybeReadable for Event { }, 13u8 => { let f = || { - let mut payment_id = PaymentId([0; 32]); - let mut payment_hash = None; - let mut path: Option> = Some(vec![]); - read_tlv_fields!(reader, { + _init_and_read_tlv_fields!(reader, { (0, payment_id, required), (2, payment_hash, option), (4, path, vec_type), + (6, blinded_tail, option), }); Ok(Some(Event::PaymentPathSuccessful { - payment_id, + payment_id: payment_id.0.unwrap(), payment_hash, - path: path.unwrap(), + path: Path { hops: path.unwrap(), blinded_tail }, })) }; f() @@ -1145,13 +1272,16 @@ impl MaybeReadable for Event { let f = || { let mut payment_hash = PaymentHash([0; 32]); let mut payment_id = PaymentId([0; 32]); + let mut reason = None; read_tlv_fields!(reader, { (0, payment_id, required), + (1, reason, upgradable_option), (2, payment_hash, required), }); Ok(Some(Event::PaymentFailed { payment_id, payment_hash, + reason, })) }; f() @@ -1183,38 +1313,33 @@ impl MaybeReadable for Event { }, 21u8 => { let f = || { - let mut payment_id = PaymentId([0; 32]); - let mut payment_hash = PaymentHash([0; 32]); - let mut path: Option> = Some(vec![]); - read_tlv_fields!(reader, { + _init_and_read_tlv_fields!(reader, { (0, payment_id, required), (2, payment_hash, required), (4, path, vec_type), + (6, blinded_tail, option), }); Ok(Some(Event::ProbeSuccessful { - payment_id, - payment_hash, - path: path.unwrap(), + payment_id: payment_id.0.unwrap(), + payment_hash: payment_hash.0.unwrap(), + path: Path { hops: path.unwrap(), blinded_tail }, })) }; f() }, 23u8 => { let f = || { - let mut payment_id = PaymentId([0; 32]); - let mut payment_hash = PaymentHash([0; 32]); - let mut path: Option> = Some(vec![]); - let mut short_channel_id = None; - read_tlv_fields!(reader, { + _init_and_read_tlv_fields!(reader, { (0, payment_id, required), (2, payment_hash, required), (4, path, vec_type), (6, short_channel_id, option), + (8, blinded_tail, option), }); Ok(Some(Event::ProbeFailed { - payment_id, - payment_hash, - path: path.unwrap(), + payment_id: payment_id.0.unwrap(), + payment_hash: payment_hash.0.unwrap(), + path: Path { hops: path.unwrap(), blinded_tail }, short_channel_id, })) }; @@ -1258,6 +1383,31 @@ impl MaybeReadable for Event { }; f() }, + 31u8 => { + let f = || { + let mut channel_id = [0; 32]; + let mut user_channel_id: u128 = 0; + let mut former_temporary_channel_id = None; + let mut counterparty_node_id = RequiredWrapper(None); + let mut funding_txo = RequiredWrapper(None); + read_tlv_fields!(reader, { + (0, channel_id, required), + (2, user_channel_id, required), + (4, former_temporary_channel_id, required), + (6, counterparty_node_id, required), + (8, funding_txo, required), + }); + + Ok(Some(Event::ChannelPending { + channel_id, + user_channel_id, + former_temporary_channel_id, + counterparty_node_id: counterparty_node_id.0.unwrap(), + funding_txo: funding_txo.0.unwrap() + })) + }; + f() + }, // Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue. // Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt // reads.