- HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info,
- prev_funding_outpoint } => {
- let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
- short_channel_id: prev_short_channel_id,
- outpoint: prev_funding_outpoint,
- htlc_id: prev_htlc_id,
- incoming_packet_shared_secret: forward_info.incoming_shared_secret,
- });
- failed_forwards.push((htlc_source, forward_info.payment_hash,
- HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() }
- ));
- },
+ HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
+ routing, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value },
+ prev_funding_outpoint } => {
+ let htlc_failure_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
+ short_channel_id: prev_short_channel_id,
+ outpoint: prev_funding_outpoint,
+ htlc_id: prev_htlc_id,
+ incoming_packet_shared_secret: incoming_shared_secret,
+ });
+ macro_rules! fail_forward {
+ ($msg: expr, $err_code: expr, $err_data: expr) => {
+ {
+ log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
+ failed_forwards.push((htlc_failure_source, payment_hash,
+ HTLCFailReason::Reason { failure_code: $err_code, data: $err_data }
+ ));
+ continue;
+ }
+ }
+ }
+ macro_rules! fail_phantom_forward {
+ ($msg: expr, $err_code: expr, $err_data: expr, $phantom_shared_secret: expr) => {
+ {
+ log_info!(self.logger, "Failed to accept/forward incoming phantom node HTLC: {}", $msg);
+ let packet = onion_utils::build_failure_packet(&$phantom_shared_secret, $err_code, &$err_data[..]).encode();
+ let error_data = onion_utils::encrypt_failure_packet(&$phantom_shared_secret, &packet);
+ failed_forwards.push((htlc_failure_source, payment_hash,
+ HTLCFailReason::LightningError { err: error_data }
+ ));
+ continue;
+ }
+ }
+ }
+ if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
+ let phantom_secret_res = self.keys_manager.get_node_secret(Recipient::PhantomNode);
+ if phantom_secret_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id) {
+ let phantom_shared_secret = {
+ let mut arr = [0; 32];
+ arr.copy_from_slice(&SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap())[..]);
+ arr
+ };
+ let next_hop = match onion_utils::decode_next_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
+ Ok(res) => res,
+ Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
+ let sha256_of_onion = Sha256::hash(&onion_packet.hop_data).into_inner();
+ fail_forward!(err_msg, err_code, sha256_of_onion.to_vec());
+ },
+ Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
+ fail_phantom_forward!(err_msg, err_code, Vec::new(), phantom_shared_secret);
+ },
+ };
+ match next_hop {
+ onion_utils::Hop::Receive(hop_data) => {
+ match self.construct_recv_pending_htlc_info(hop_data, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value, Some(phantom_shared_secret)) {
+ Ok(info) => phantom_receives.push((prev_short_channel_id, prev_funding_outpoint, vec![(info, prev_htlc_id)])),
+ Err(ReceiveError { err_code, err_data, msg }) => fail_phantom_forward!(msg, err_code, err_data, phantom_shared_secret)
+ }
+ },
+ _ => panic!(),
+ }
+ } else {
+ fail_forward!(format!("Unknown short channel id {} for forward HTLC", short_chan_id), 0x4000 | 10, Vec::new());
+ }
+ } else {
+ fail_forward!(format!("Unknown short channel id {} for forward HTLC", short_chan_id), 0x4000 | 10, Vec::new());
+ }
+ },