X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fonion_utils.rs;h=4b39276c066c77ec5975be569c274081158750ed;hb=e142e4a4e6c856f533ec350ae61c1bbe2a3f20e9;hp=b7da2fd882d516d559e5f6e3e8a26ffe379eeddb;hpb=e1ed52fae77794e2c64adb8737c64be6e264a631;p=rust-lightning diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index b7da2fd8..4b39276c 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -14,7 +14,8 @@ use crate::ln::wire::Encode; use crate::routing::gossip::NetworkUpdate; use crate::routing::router::{BlindedTail, Path, RouteHop}; use crate::sign::NodeSigner; -use crate::util::chacha20::{ChaCha20, ChaChaReader}; +use crate::crypto::chacha20::ChaCha20; +use crate::crypto::streams::ChaChaReader; use crate::util::errors::{self, APIError}; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, LengthCalculatingWriter}; use crate::util::logger::Logger; @@ -188,11 +189,10 @@ pub(super) fn build_onion_payloads(path: &Path, total_msat: u64, mut recipient_o for (i, blinded_hop) in hops.iter().enumerate() { if i == hops.len() - 1 { cur_value_msat += final_value_msat; - cur_cltv += excess_final_cltv_expiry_delta; res.push(msgs::OutboundOnionPayload::BlindedReceive { - amt_msat: *final_value_msat, + sender_intended_htlc_amt_msat: *final_value_msat, total_msat, - outgoing_cltv_value: cltv, + cltv_expiry_height: cur_cltv + excess_final_cltv_expiry_delta, encrypted_tlvs: blinded_hop.encrypted_payload.clone(), intro_node_blinding_point: blinding_point.take(), }); @@ -214,8 +214,8 @@ pub(super) fn build_onion_payloads(path: &Path, total_msat: u64, mut recipient_o payment_metadata: recipient_onion.payment_metadata.take(), keysend_preimage: *keysend_preimage, custom_tlvs: recipient_onion.custom_tlvs.clone(), - amt_msat: value_msat, - outgoing_cltv_value: cltv, + sender_intended_htlc_amt_msat: value_msat, + cltv_expiry_height: cltv, }); } } else { @@ -323,8 +323,6 @@ fn construct_onion_packet_with_init_noise( let mut pos = 0; for (i, (payload, keys)) in payloads.iter().zip(onion_keys.iter()).enumerate() { - if i == payloads.len() - 1 { break; } - let mut chacha = ChaCha20::new(&keys.rho, &[0u8; 8]); for _ in 0..(packet_data.len() - pos) { // TODO: Batch this. let mut dummy = [0; 1]; @@ -338,6 +336,8 @@ fn construct_onion_packet_with_init_noise( return Err(()); } + if i == payloads.len() - 1 { break; } + res.resize(pos, 0u8); chacha.process_in_place(&mut res); } @@ -429,6 +429,7 @@ pub(crate) struct DecodedOnionFailure { pub(crate) network_update: Option, pub(crate) short_channel_id: Option, pub(crate) payment_failed_permanently: bool, + pub(crate) failed_within_blinded_path: bool, #[cfg(test)] pub(crate) onion_error_code: Option, #[cfg(test)] @@ -463,6 +464,7 @@ pub(super) fn process_onion_failure( network_update: Option, short_channel_id: Option, payment_failed_permanently: bool, + failed_within_blinded_path: bool, } let mut res: Option = None; let mut htlc_msat = *first_hop_htlc_msat; @@ -488,7 +490,8 @@ pub(super) fn process_onion_failure( error_code_ret = Some(BADONION | PERM | 24); // invalid_onion_blinding error_packet_ret = Some(vec![0; 32]); res = Some(FailureLearnings { - network_update: None, short_channel_id: None, payment_failed_permanently: false + network_update: None, short_channel_id: None, payment_failed_permanently: false, + failed_within_blinded_path: true, }); return }, @@ -520,7 +523,8 @@ pub(super) fn process_onion_failure( } res = Some(FailureLearnings { - network_update: None, short_channel_id: None, payment_failed_permanently: false + network_update: None, short_channel_id: None, payment_failed_permanently: false, + failed_within_blinded_path: true, }); return } @@ -550,7 +554,8 @@ pub(super) fn process_onion_failure( }); let short_channel_id = Some(route_hop.short_channel_id); res = Some(FailureLearnings { - network_update, short_channel_id, payment_failed_permanently: is_from_final_node + network_update, short_channel_id, payment_failed_permanently: is_from_final_node, + failed_within_blinded_path: false }); return } @@ -706,7 +711,8 @@ pub(super) fn process_onion_failure( res = Some(FailureLearnings { network_update, short_channel_id, - payment_failed_permanently: error_code & PERM == PERM && is_from_final_node + payment_failed_permanently: error_code & PERM == PERM && is_from_final_node, + failed_within_blinded_path: false }); let (description, title) = errors::get_onion_error_description(error_code); @@ -717,10 +723,10 @@ pub(super) fn process_onion_failure( } }).expect("Route that we sent via spontaneously grew invalid keys in the middle of it?"); if let Some(FailureLearnings { - network_update, short_channel_id, payment_failed_permanently + network_update, short_channel_id, payment_failed_permanently, failed_within_blinded_path }) = res { DecodedOnionFailure { - network_update, short_channel_id, payment_failed_permanently, + network_update, short_channel_id, payment_failed_permanently, failed_within_blinded_path, #[cfg(test)] onion_error_code: error_code_ret, #[cfg(test)] @@ -731,6 +737,7 @@ pub(super) fn process_onion_failure( // payment not retryable only when garbage is from the final node DecodedOnionFailure { network_update: None, short_channel_id: None, payment_failed_permanently: is_from_final_node, + failed_within_blinded_path: false, #[cfg(test)] onion_error_code: None, #[cfg(test)] @@ -878,6 +885,7 @@ impl HTLCFailReason { network_update: None, payment_failed_permanently: false, short_channel_id: Some(path.hops[0].short_channel_id), + failed_within_blinded_path: false, #[cfg(test)] onion_error_code: Some(*failure_code), #[cfg(test)] @@ -1023,18 +1031,20 @@ fn decode_next_hop, N: NextPacketBytes>(shared_secret: [u8 if hmac == [0; 32] { #[cfg(test)] { - // In tests, make sure that the initial onion packet data is, at least, non-0. - // We could do some fancy randomness test here, but, ehh, whatever. - // This checks for the issue where you can calculate the path length given the - // onion data as all the path entries that the originator sent will be here - // as-is (and were originally 0s). - // Of course reverse path calculation is still pretty easy given naive routing - // algorithms, but this fixes the most-obvious case. - let mut next_bytes = [0; 32]; - chacha_stream.read_exact(&mut next_bytes).unwrap(); - assert_ne!(next_bytes[..], [0; 32][..]); - chacha_stream.read_exact(&mut next_bytes).unwrap(); - assert_ne!(next_bytes[..], [0; 32][..]); + if chacha_stream.read.position() < hop_data.len() as u64 - 64 { + // In tests, make sure that the initial onion packet data is, at least, non-0. + // We could do some fancy randomness test here, but, ehh, whatever. + // This checks for the issue where you can calculate the path length given the + // onion data as all the path entries that the originator sent will be here + // as-is (and were originally 0s). + // Of course reverse path calculation is still pretty easy given naive routing + // algorithms, but this fixes the most-obvious case. + let mut next_bytes = [0; 32]; + chacha_stream.read_exact(&mut next_bytes).unwrap(); + assert_ne!(next_bytes[..], [0; 32][..]); + chacha_stream.read_exact(&mut next_bytes).unwrap(); + assert_ne!(next_bytes[..], [0; 32][..]); + } } return Ok((msg, None)); // We are the final destination for this packet } else {