X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fonion_utils.rs;h=598edcf0367952b011e290bfe48938ec92364ecb;hb=a257906743d528c32c862b053b652d4b728aa990;hp=3795ad5ee77d70a03e5124fc3800823f610e0634;hpb=7e05623befc111422d1d4230f4e51629566a2ae6;p=rust-lightning diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 3795ad5e..598edcf0 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -7,16 +7,16 @@ // You may not use this file except in accordance with one or both of these // licenses. -use ln::{PaymentHash, PaymentPreimage, PaymentSecret}; -use ln::channelmanager::HTLCSource; -use ln::msgs; -use ln::wire::Encode; -use routing::gossip::NetworkUpdate; -use routing::router::RouteHop; -use util::chacha20::{ChaCha20, ChaChaReader}; -use util::errors::{self, APIError}; -use util::ser::{Readable, ReadableArgs, Writeable, LengthCalculatingWriter}; -use util::logger::Logger; +use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; +use crate::ln::channelmanager::HTLCSource; +use crate::ln::msgs; +use crate::ln::wire::Encode; +use crate::routing::gossip::NetworkUpdate; +use crate::routing::router::RouteHop; +use crate::util::chacha20::{ChaCha20, ChaChaReader}; +use crate::util::errors::{self, APIError}; +use crate::util::ser::{Readable, ReadableArgs, Writeable, LengthCalculatingWriter}; +use crate::util::logger::Logger; use bitcoin::hashes::{Hash, HashEngine}; use bitcoin::hashes::cmp::fixed_time_eq; @@ -28,8 +28,8 @@ use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::ecdh::SharedSecret; use bitcoin::secp256k1; -use prelude::*; -use io::{Cursor, Read}; +use crate::prelude::*; +use crate::io::{Cursor, Read}; use core::convert::{AsMut, TryInto}; use core::ops::Deref; @@ -425,6 +425,7 @@ pub(super) fn process_onion_failure(secp_ctx: & if fixed_time_eq(&Hmac::from_engine(hmac).into_inner(), &err_packet.hmac) { if let Some(error_code_slice) = err_packet.failuremsg.get(0..2) { + const BADONION: u16 = 0x8000; const PERM: u16 = 0x4000; const NODE: u16 = 0x2000; const UPDATE: u16 = 0x1000; @@ -445,12 +446,24 @@ pub(super) fn process_onion_failure(secp_ctx: & let mut network_update = None; let mut short_channel_id = None; - if error_code & NODE == NODE { + if error_code & BADONION == BADONION { + // If the error code has the BADONION bit set, always blame the channel + // from the node "originating" the error to its next hop. The + // "originator" is ultimately actually claiming that its counterparty + // is the one who is failing the HTLC. + // If the "originator" here isn't lying we should really mark the + // next-hop node as failed entirely, but we can't be confident in that, + // as it would allow any node to get us to completely ban one of its + // counterparties. Instead, we simply remove the channel in question. + network_update = Some(NetworkUpdate::ChannelFailure { + short_channel_id: failing_route_hop.short_channel_id, + is_permanent: true, + }); + } else if error_code & NODE == NODE { let is_permanent = error_code & PERM == PERM; network_update = Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent }); short_channel_id = Some(route_hop.short_channel_id); - } - else if error_code & PERM == PERM { + } else if error_code & PERM == PERM { if !payment_failed { network_update = Some(NetworkUpdate::ChannelFailure { short_channel_id: failing_route_hop.short_channel_id, @@ -458,8 +471,7 @@ pub(super) fn process_onion_failure(secp_ctx: & }); short_channel_id = Some(failing_route_hop.short_channel_id); } - } - else if error_code & UPDATE == UPDATE { + } else if error_code & UPDATE == UPDATE { if let Some(update_len_slice) = err_packet.failuremsg.get(debug_field_size+2..debug_field_size+4) { let update_len = u16::from_be_bytes(update_len_slice.try_into().expect("len is 2")) as usize; if let Some(mut update_slice) = err_packet.failuremsg.get(debug_field_size + 4..debug_field_size + 4 + update_len) { @@ -545,9 +557,6 @@ pub(super) fn process_onion_failure(secp_ctx: & short_channel_id = Some(route_hop.short_channel_id); } - // TODO: Here (and a few other places) we assume that BADONION errors - // are always "sourced" from the node previous to the one which failed - // to decode the onion. res = Some((network_update, short_channel_id, !(error_code & PERM == PERM && is_from_final_node))); let (description, title) = errors::get_onion_error_description(error_code); @@ -747,13 +756,13 @@ pub(crate) fn decode_next_hop, N: NextPa #[cfg(test)] mod tests { - use io; - use prelude::*; - use ln::PaymentHash; - use ln::features::{ChannelFeatures, NodeFeatures}; - use routing::router::{Route, RouteHop}; - use ln::msgs; - use util::ser::{Writeable, Writer}; + use crate::io; + use crate::prelude::*; + use crate::ln::PaymentHash; + use crate::ln::features::{ChannelFeatures, NodeFeatures}; + use crate::routing::router::{Route, RouteHop}; + use crate::ln::msgs; + use crate::util::ser::{Writeable, Writer}; use hex;