Move `HTLCFailReason` to `onion_utils`
authorMatt Corallo <git@bluematt.me>
Thu, 1 Dec 2022 19:20:19 +0000 (19:20 +0000)
committerMatt Corallo <git@bluematt.me>
Tue, 6 Dec 2022 20:00:44 +0000 (20:00 +0000)
Now that it's entirely abstracted, there's no reason for
`HTLCFailReason` to be in `channelmanager`, it's really an
onion-level abstraction.

lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/onion_utils.rs

index 5cc4f4a364bf3fe80ab15b896b51557a58acc5d1..9f47bacc74de03f3e3d7b234f5db14ddbdb0cdad 100644 (file)
@@ -27,9 +27,10 @@ use crate::ln::features::{ChannelTypeFeatures, InitFeatures};
 use crate::ln::msgs;
 use crate::ln::msgs::{DecodeError, OptionalField, DataLossProtect};
 use crate::ln::script::{self, ShutdownScript};
-use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
+use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
 use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, htlc_success_tx_weight, htlc_timeout_tx_weight, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor, ClosingTransaction};
 use crate::ln::chan_utils;
+use crate::ln::onion_utils::HTLCFailReason;
 use crate::chain::BestBlock;
 use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator};
 use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
index eddb5589e4ffb4e4232ce100c6b818a55f4b6c4f..7fed7b2f4277bd7479e7bfc5cf96abe27ebf9c59 100644 (file)
@@ -49,6 +49,7 @@ use crate::ln::features::InvoiceFeatures;
 use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RoutePath, RouteParameters};
 use crate::ln::msgs;
 use crate::ln::onion_utils;
+use crate::ln::onion_utils::HTLCFailReason;
 use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT};
 use crate::ln::wire::Encode;
 use crate::chain::keysinterface::{Sign, KeysInterface, KeysManager, Recipient};
@@ -276,82 +277,6 @@ impl HTLCSource {
        }
 }
 
-#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
-pub(super) enum HTLCFailReason {
-       LightningError {
-               err: msgs::OnionErrorPacket,
-       },
-       Reason {
-               failure_code: u16,
-               data: Vec<u8>,
-       }
-}
-
-impl core::fmt::Debug for HTLCFailReason {
-       fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
-               match self {
-                       HTLCFailReason::Reason { ref failure_code, .. } => {
-                               write!(f, "HTLC error code {}", failure_code)
-                       },
-                       HTLCFailReason::LightningError { .. } => {
-                               write!(f, "pre-built LightningError")
-                       }
-               }
-       }
-}
-
-impl HTLCFailReason {
-       pub(super) fn reason(failure_code: u16, data: Vec<u8>) -> Self {
-               Self::Reason { failure_code, data }
-       }
-
-       pub(super) fn from_failure_code(failure_code: u16) -> Self {
-               Self::Reason { failure_code, data: Vec::new() }
-       }
-
-       pub(super) fn from_msg(msg: &msgs::UpdateFailHTLC) -> Self {
-               Self::LightningError { err: msg.reason.clone() }
-       }
-
-       fn get_encrypted_failure_packet(&self, incoming_packet_shared_secret: &[u8; 32], phantom_shared_secret: &Option<[u8; 32]>) -> msgs::OnionErrorPacket {
-               match self {
-                       HTLCFailReason::Reason { ref failure_code, ref data } => {
-                               if let Some(phantom_ss) = phantom_shared_secret {
-                                       let phantom_packet = onion_utils::build_failure_packet(phantom_ss, *failure_code, &data[..]).encode();
-                                       let encrypted_phantom_packet = onion_utils::encrypt_failure_packet(phantom_ss, &phantom_packet);
-                                       onion_utils::encrypt_failure_packet(incoming_packet_shared_secret, &encrypted_phantom_packet.data[..])
-                               } else {
-                                       let packet = onion_utils::build_failure_packet(incoming_packet_shared_secret, *failure_code, &data[..]).encode();
-                                       onion_utils::encrypt_failure_packet(incoming_packet_shared_secret, &packet)
-                               }
-                       },
-                       HTLCFailReason::LightningError { err } => {
-                               onion_utils::encrypt_failure_packet(incoming_packet_shared_secret, &err.data)
-                       }
-               }
-       }
-
-       fn decode_onion_failure<T: secp256k1::Signing, L: Deref>(&self, secp_ctx: &Secp256k1<T>, logger: &L, htlc_source: &HTLCSource) -> (Option<crate::routing::gossip::NetworkUpdate>, Option<u64>, bool, Option<u16>, Option<Vec<u8>>) where L::Target: Logger {
-               match self {
-                       HTLCFailReason::LightningError { ref err } => {
-                               onion_utils::process_onion_failure(secp_ctx, logger, &htlc_source, err.data.clone())
-                       },
-                       HTLCFailReason::Reason { ref failure_code, ref data, .. } => {
-                               // we get a fail_malformed_htlc from the first hop
-                               // TODO: We'd like to generate a NetworkUpdate for temporary
-                               // failures here, but that would be insufficient as find_route
-                               // generally ignores its view of our own channels as we provide them via
-                               // ChannelDetails.
-                               // TODO: For non-temporary failures, we really should be closing the
-                               // channel here as we apparently can't relay through them anyway.
-                               if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
-                                       (None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
-                               } else { unreachable!(); }
-                       }
-               }
-       }
-}
-
 struct ReceiveError {
        err_code: u16,
        err_data: Vec<u8>,
@@ -7031,16 +6956,6 @@ impl Writeable for HTLCSource {
        }
 }
 
-impl_writeable_tlv_based_enum!(HTLCFailReason,
-       (0, LightningError) => {
-               (0, err, required),
-       },
-       (1, Reason) => {
-               (0, failure_code, required),
-               (2, data, vec_type),
-       },
-;);
-
 impl_writeable_tlv_based!(PendingAddHTLCInfo, {
        (0, forward_info, required),
        (1, prev_user_channel_id, (default_value, 0)),
index 23dc556cfacca4f129d7968323f997a0f3c63692..a44e9b37d04a260f85c7de68e4da7c97f9c12e05 100644 (file)
@@ -592,6 +592,94 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
        } else { unreachable!(); }
 }
 
+#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
+pub(super) enum HTLCFailReason {
+       LightningError {
+               err: msgs::OnionErrorPacket,
+       },
+       Reason {
+               failure_code: u16,
+               data: Vec<u8>,
+       }
+}
+
+impl core::fmt::Debug for HTLCFailReason {
+       fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
+               match self {
+                       HTLCFailReason::Reason { ref failure_code, .. } => {
+                               write!(f, "HTLC error code {}", failure_code)
+                       },
+                       HTLCFailReason::LightningError { .. } => {
+                               write!(f, "pre-built LightningError")
+                       }
+               }
+       }
+}
+
+impl_writeable_tlv_based_enum!(HTLCFailReason,
+       (0, LightningError) => {
+               (0, err, required),
+       },
+       (1, Reason) => {
+               (0, failure_code, required),
+               (2, data, vec_type),
+       },
+;);
+
+impl HTLCFailReason {
+       pub(super) fn reason(failure_code: u16, data: Vec<u8>) -> Self {
+               Self::Reason { failure_code, data }
+       }
+
+       pub(super) fn from_failure_code(failure_code: u16) -> Self {
+               Self::Reason { failure_code, data: Vec::new() }
+       }
+
+       pub(super) fn from_msg(msg: &msgs::UpdateFailHTLC) -> Self {
+               Self::LightningError { err: msg.reason.clone() }
+       }
+
+       pub(super) fn get_encrypted_failure_packet(&self, incoming_packet_shared_secret: &[u8; 32], phantom_shared_secret: &Option<[u8; 32]>)
+       -> msgs::OnionErrorPacket {
+               match self {
+                       HTLCFailReason::Reason { ref failure_code, ref data } => {
+                               if let Some(phantom_ss) = phantom_shared_secret {
+                                       let phantom_packet = build_failure_packet(phantom_ss, *failure_code, &data[..]).encode();
+                                       let encrypted_phantom_packet = encrypt_failure_packet(phantom_ss, &phantom_packet);
+                                       encrypt_failure_packet(incoming_packet_shared_secret, &encrypted_phantom_packet.data[..])
+                               } else {
+                                       let packet = build_failure_packet(incoming_packet_shared_secret, *failure_code, &data[..]).encode();
+                                       encrypt_failure_packet(incoming_packet_shared_secret, &packet)
+                               }
+                       },
+                       HTLCFailReason::LightningError { err } => {
+                               encrypt_failure_packet(incoming_packet_shared_secret, &err.data)
+                       }
+               }
+       }
+
+       pub(super) fn decode_onion_failure<T: secp256k1::Signing, L: Deref>(
+               &self, secp_ctx: &Secp256k1<T>, logger: &L, htlc_source: &HTLCSource
+       ) -> (Option<NetworkUpdate>, Option<u64>, bool, Option<u16>, Option<Vec<u8>>)
+       where L::Target: Logger {
+               match self {
+                       HTLCFailReason::LightningError { ref err } => {
+                               process_onion_failure(secp_ctx, logger, &htlc_source, err.data.clone())
+                       },
+                       HTLCFailReason::Reason { ref failure_code, ref data, .. } => {
+                               // we get a fail_malformed_htlc from the first hop
+                               // TODO: We'd like to generate a NetworkUpdate for temporary
+                               // failures here, but that would be insufficient as find_route
+                               // generally ignores its view of our own channels as we provide them via
+                               // ChannelDetails.
+                               if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
+                                       (None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
+                               } else { unreachable!(); }
+                       }
+               }
+       }
+}
+
 /// Allows `decode_next_hop` to return the next hop packet bytes for either payments or onion
 /// message forwards.
 pub(crate) trait NextPacketBytes: AsMut<[u8]> {