mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 07:17:40 +01:00
Move HTLCFailReason
to onion_utils
Now that it's entirely abstracted, there's no reason for `HTLCFailReason` to be in `channelmanager`, it's really an onion-level abstraction.
This commit is contained in:
parent
4ba83381b1
commit
2485ef38c3
3 changed files with 91 additions and 87 deletions
|
@ -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};
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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]> {
|
||||
|
|
Loading…
Add table
Reference in a new issue