X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fonion_utils.rs;h=ee3ed96b5ef0efdcaaeda40a32f2e71653948ac0;hb=801d6e5256d6ac91d5d5668da1fa5a2b55303246;hp=07686a214e23c90c3e1166bca19580da55309777;hpb=3a0356fe308ba29916d00f3376cd57ce6613f3d0;p=rust-lightning diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 07686a21..ee3ed96b 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -7,11 +7,11 @@ // You may not use this file except in accordance with one or both of these // licenses. -use ln::{PaymentHash, PaymentSecret}; +use ln::{PaymentHash, PaymentPreimage, PaymentSecret}; use ln::channelmanager::HTLCSource; use ln::msgs; +use routing::network_graph::NetworkUpdate; use routing::router::RouteHop; -use util::byte_utils; use util::chacha20::ChaCha20; use util::errors::{self, APIError}; use util::ser::{Readable, Writeable, LengthCalculatingWriter}; @@ -27,7 +27,9 @@ use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::ecdh::SharedSecret; use bitcoin::secp256k1; -use std::io::Cursor; +use prelude::*; +use io::Cursor; +use core::convert::TryInto; use core::ops::Deref; pub(super) struct OnionKeys { @@ -118,7 +120,7 @@ pub(super) fn construct_onion_keys(secp_ctx: &Secp256k1, total_msat: u64, payment_secret_option: &Option, starting_htlc_offset: u32) -> Result<(Vec, u64, u32), APIError> { +pub(super) fn build_onion_payloads(path: &Vec, total_msat: u64, payment_secret_option: &Option, starting_htlc_offset: u32, keysend_preimage: &Option) -> Result<(Vec, u64, u32), APIError> { let mut cur_value_msat = 0u64; let mut cur_cltv = starting_htlc_offset; let mut last_short_channel_id = 0; @@ -140,6 +142,7 @@ pub(super) fn build_onion_payloads(path: &Vec, total_msat: u64, paymen total_msat, }) } else { None }, + keysend_preimage: *keysend_preimage, } } else { msgs::OnionHopDataFormat::NonFinalNode { @@ -328,8 +331,8 @@ pub(super) fn build_first_hop_failure_packet(shared_secret: &[u8], failure_type: /// OutboundRoute). /// Returns update, a boolean indicating that the payment itself failed, and the error code. #[inline] -pub(super) fn process_onion_failure(secp_ctx: &Secp256k1, logger: &L, htlc_source: &HTLCSource, mut packet_decrypted: Vec) -> (Option, bool, Option, Option>) where L::Target: Logger { - if let &HTLCSource::OutboundRoute { ref path, ref session_priv, ref first_hop_htlc_msat } = htlc_source { +pub(super) fn process_onion_failure(secp_ctx: &Secp256k1, logger: &L, htlc_source: &HTLCSource, mut packet_decrypted: Vec) -> (Option, bool, Option, Option>) where L::Target: Logger { + if let &HTLCSource::OutboundRoute { ref path, ref session_priv, ref first_hop_htlc_msat, .. } = htlc_source { let mut res = None; let mut htlc_msat = *first_hop_htlc_msat; let mut error_code_ret = None; @@ -366,7 +369,7 @@ pub(super) fn process_onion_failure(secp_ctx: & const NODE: u16 = 0x2000; const UPDATE: u16 = 0x1000; - let error_code = byte_utils::slice_to_be16(&error_code_slice); + let error_code = u16::from_be_bytes(error_code_slice.try_into().expect("len is 2")); error_code_ret = Some(error_code); error_packet_ret = Some(err_packet.failuremsg[2..].to_vec()); @@ -380,20 +383,20 @@ pub(super) fn process_onion_failure(secp_ctx: & } && is_from_final_node) // PERM bit observed below even this error is from the intermediate nodes || error_code == 21; // Special case error 21 as the Route object is bogus, TODO: Maybe fail the node if the CLTV was reasonable? - let mut fail_channel_update = None; + let mut network_update = None; if error_code & NODE == NODE { - fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: error_code & PERM == PERM }); + network_update = Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: error_code & PERM == PERM }); } else if error_code & PERM == PERM { - fail_channel_update = if payment_failed {None} else {Some(msgs::HTLCFailChannelUpdate::ChannelClosed { + network_update = if payment_failed { None } else { Some(NetworkUpdate::ChannelClosed { short_channel_id: path[next_route_hop_ix - if next_route_hop_ix == path.len() { 1 } else { 0 }].short_channel_id, is_permanent: true, })}; } 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 = byte_utils::slice_to_be16(&update_len_slice) as usize; + let update_len = u16::from_be_bytes(update_len_slice.try_into().expect("len is 2")) as usize; if let Some(update_slice) = err_packet.failuremsg.get(debug_field_size + 4..debug_field_size + 4 + update_len) { if let Ok(chan_update) = msgs::ChannelUpdate::read(&mut Cursor::new(&update_slice)) { // if channel_update should NOT have caused the failure: @@ -410,25 +413,25 @@ pub(super) fn process_onion_failure(secp_ctx: & 20 => chan_update.contents.flags & 2 == 0, _ => false, // unknown error code; take channel_update as valid }; - fail_channel_update = if is_chan_update_invalid { + network_update = if is_chan_update_invalid { // This probably indicates the node which forwarded // to the node in question corrupted something. - Some(msgs::HTLCFailChannelUpdate::ChannelClosed { + Some(NetworkUpdate::ChannelClosed { short_channel_id: route_hop.short_channel_id, is_permanent: true, }) } else { - Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { + Some(NetworkUpdate::ChannelUpdateMessage { msg: chan_update, }) }; } } } - if fail_channel_update.is_none() { + if network_update.is_none() { // They provided an UPDATE which was obviously bogus, not worth // trying to relay through them anymore. - fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure { + network_update = Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: true, }); @@ -437,7 +440,7 @@ pub(super) fn process_onion_failure(secp_ctx: & // We can't understand their error messages and they failed to // forward...they probably can't understand our forwards so its // really not worth trying any further. - fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure { + network_update = Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: true, }); @@ -446,7 +449,7 @@ pub(super) fn process_onion_failure(secp_ctx: & // 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((fail_channel_update, !(error_code & PERM == PERM && is_from_final_node))); + res = Some((network_update, !(error_code & PERM == PERM && is_from_final_node))); let (description, title) = errors::get_onion_error_description(error_code); if debug_field_size > 0 && err_packet.failuremsg.len() >= 4 + debug_field_size { @@ -458,7 +461,7 @@ pub(super) fn process_onion_failure(secp_ctx: & } else { // Useless packet that we can't use but it passed HMAC, so it // definitely came from the peer in question - res = Some((Some(msgs::HTLCFailChannelUpdate::NodeFailure { + res = Some((Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: true, }), !is_from_final_node)); @@ -478,6 +481,8 @@ pub(super) fn process_onion_failure(secp_ctx: & #[cfg(test)] mod tests { + use io; + use prelude::*; use ln::PaymentHash; use ln::features::{ChannelFeatures, NodeFeatures}; use routing::router::{Route, RouteHop}; @@ -645,7 +650,7 @@ mod tests { } } impl Writeable for RawOnionHopData { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { writer.write_all(&self.data[..]) } }