use std::{ptr, mem};
use std::time::{Instant,Duration};
-/// Stores the info we will need to send when we want to forward an HTLC onwards
-pub struct PendingForwardHTLCInfo {
- onion_packet: Option<msgs::OnionPacket>,
- payment_hash: [u8; 32],
- short_channel_id: u64,
- prev_short_channel_id: u64,
- amt_to_forward: u64,
- outgoing_cltv_value: u32,
-}
+mod channel_held_info {
+ use ln::msgs;
-#[cfg(feature = "fuzztarget")]
-impl PendingForwardHTLCInfo {
- pub fn dummy() -> Self {
- Self {
- onion_packet: None,
- payment_hash: [0; 32],
- short_channel_id: 0,
- prev_short_channel_id: 0,
- amt_to_forward: 0,
- outgoing_cltv_value: 0,
+ /// Stores the info we will need to send when we want to forward an HTLC onwards
+ pub struct PendingForwardHTLCInfo {
+ onion_packet: Option<msgs::OnionPacket>,
+ payment_hash: [u8; 32],
+ short_channel_id: u64,
+ prev_short_channel_id: u64,
+ amt_to_forward: u64,
+ outgoing_cltv_value: u32,
+ }
+
+ #[cfg(feature = "fuzztarget")]
+ impl PendingForwardHTLCInfo {
+ pub fn dummy() -> Self {
+ Self {
+ onion_packet: None,
+ payment_hash: [0; 32],
+ short_channel_id: 0,
+ prev_short_channel_id: 0,
+ amt_to_forward: 0,
+ outgoing_cltv_value: 0,
+ }
+ }
+ }
+
+ pub enum HTLCFailReason {
+ ErrorPacket {
+ err: msgs::OnionErrorPacket,
+ },
+ Reason {
+ failure_code: u16,
+ data: Vec<u8>,
}
}
}
+#[cfg(feature = "fuzztarget")]
+pub use self::channel_held_info::*;
+#[cfg(not(feature = "fuzztarget"))]
+pub(crate) use self::channel_held_info::*;
enum PendingOutboundHTLC {
IntermediaryHopData {
}
}
-enum HTLCFailReason<'a> {
- ErrorPacket {
- err: &'a msgs::OnionErrorPacket,
- },
- Reason {
- failure_code: u16,
- data: &'a[u8],
- }
-}
-
/// We hold back HTLCs we intend to relay for a random interval in the range (this, 5*this). This
/// provides some limited amount of privacy. Ideally this would range from somewhere like 1 second
/// to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly. We could
};
for payment_hash in res.1 {
// unknown_next_peer...I dunno who that is anymore....
- self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: &[0; 0] });
+ self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() });
}
Ok(res.0)
}
for failed_forward in failed_forwards.drain(..) {
match failed_forward.2 {
- None => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &failed_forward.0, HTLCFailReason::Reason { failure_code: failed_forward.1, data: &[0;0] }),
- Some(chan_update) => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &failed_forward.0, HTLCFailReason::Reason { failure_code: failed_forward.1, data: &chan_update.encode()[..] }),
+ None => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &failed_forward.0, HTLCFailReason::Reason { failure_code: failed_forward.1, data: Vec::new() }),
+ Some(chan_update) => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &failed_forward.0, HTLCFailReason::Reason { failure_code: failed_forward.1, data: chan_update.encode() }),
};
}
/// Indicates that the preimage for payment_hash is unknown after a PaymentReceived event.
pub fn fail_htlc_backwards(&self, payment_hash: &[u8; 32]) -> bool {
- self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: &[0;0] })
+ self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: Vec::new() })
}
fn fail_htlc_backwards_internal(&self, mut channel_state: MutexGuard<ChannelHolder>, payment_hash: &[u8; 32], onion_error: HTLCFailReason) -> bool {
PendingOutboundHTLC::IntermediaryHopData { source_short_channel_id, incoming_packet_shared_secret } => {
let err_packet = match onion_error {
HTLCFailReason::Reason { failure_code, data } => {
- let packet = ChannelManager::build_failure_packet(&incoming_packet_shared_secret, failure_code, data).encode();
+ let packet = ChannelManager::build_failure_packet(&incoming_packet_shared_secret, failure_code, &data[..]).encode();
ChannelManager::encrypt_failure_packet(&incoming_packet_shared_secret, &packet)
},
HTLCFailReason::ErrorPacket { err } => {
/// Provides a payment preimage in response to a PaymentReceived event, returning true and
/// generating message events for the net layer to claim the payment, if possible. Thus, you
/// should probably kick the net layer to go send messages if this returns true!
+ /// May panic if called except in response to a PaymentReceived event.
pub fn claim_funds(&self, payment_preimage: [u8; 32]) -> bool {
self.claim_funds_internal(payment_preimage, true)
}
};
for payment_hash in res.2 {
// unknown_next_peer...I dunno who that is anymore....
- self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: &[0; 0] });
+ self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() });
}
Ok((res.0, res.1))
}
}
fn handle_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFulfillHTLC) -> Result<(), HandleError> {
+ //TODO: Delay the claimed_funds relaying just like we do outbound relay!
+ // Claim funds first, cause we don't really care if the channel we received the message on
+ // is broken, we may have enough info to get our own money!
+ self.claim_funds_internal(msg.payment_preimage.clone(), false);
+
let monitor = {
let mut channel_state = self.channel_state.lock().unwrap();
match channel_state.by_id.get_mut(&msg.channel_id) {
None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
}
};
- //TODO: Delay the claimed_funds relaying just like we do outbound relay!
- self.claim_funds_internal(msg.payment_preimage.clone(), false);
self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor)?;
Ok(())
}
},
None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
};
- self.fail_htlc_backwards_internal(channel_state, &payment_hash, HTLCFailReason::ErrorPacket { err: &msg.reason });
+ self.fail_htlc_backwards_internal(channel_state, &payment_hash, HTLCFailReason::ErrorPacket { err: msg.reason.clone() });
Ok(())
}
},
None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
};
- self.fail_htlc_backwards_internal(channel_state, &payment_hash, HTLCFailReason::Reason { failure_code: msg.failure_code, data: &[0;0] });
+ self.fail_htlc_backwards_internal(channel_state, &payment_hash, HTLCFailReason::Reason { failure_code: msg.failure_code, data: Vec::new() });
Ok(())
}