Add `send_probe` and introduce probing cookies
[rust-lightning] / lightning / src / ln / onion_utils.rs
index e9e64491c0eeb461ef52d6965495836dfa6232d8..b223a344dbe204aafcd511c5efc2d4e035cf1ba9 100644 (file)
@@ -10,7 +10,8 @@
 use ln::{PaymentHash, PaymentPreimage, PaymentSecret};
 use ln::channelmanager::HTLCSource;
 use ln::msgs;
-use routing::network_graph::NetworkUpdate;
+use ln::wire::Encode;
+use routing::gossip::NetworkUpdate;
 use routing::router::RouteHop;
 use util::chacha20::{ChaCha20, ChaChaReader};
 use util::errors::{self, APIError};
@@ -73,6 +74,17 @@ pub(super) fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
        Hmac::from_engine(hmac).into_inner()
 }
 
+pub(super) fn next_hop_packet_pubkey<T: secp256k1::Signing + secp256k1::Verification>(secp_ctx: &Secp256k1<T>, mut packet_pubkey: PublicKey, packet_shared_secret: &[u8; 32]) -> Result<PublicKey, secp256k1::Error> {
+       let blinding_factor = {
+               let mut sha = Sha256::engine();
+               sha.input(&packet_pubkey.serialize()[..]);
+               sha.input(packet_shared_secret);
+               Sha256::from_engine(sha).into_inner()
+       };
+
+       packet_pubkey.mul_assign(secp_ctx, &blinding_factor[..]).map(|_| packet_pubkey)
+}
+
 // can only fail if an intermediary hop has an invalid public key or session_priv is invalid
 #[inline]
 pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(SharedSecret, [u8; 32], PublicKey, &RouteHop, usize)> (secp_ctx: &Secp256k1<T>, path: &Vec<RouteHop>, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {
@@ -394,7 +406,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
                                                }
                                                else if error_code & PERM == PERM {
                                                        if !payment_failed {
-                                                               network_update = Some(NetworkUpdate::ChannelClosed {
+                                                               network_update = Some(NetworkUpdate::ChannelFailure {
                                                                        short_channel_id: failing_route_hop.short_channel_id,
                                                                        is_permanent: true,
                                                                });
@@ -404,7 +416,21 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
                                                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(update_slice) = err_packet.failuremsg.get(debug_field_size + 4..debug_field_size + 4 + update_len) {
+                                                               if let Some(mut update_slice) = err_packet.failuremsg.get(debug_field_size + 4..debug_field_size + 4 + update_len) {
+                                                                       // Historically, the BOLTs were unclear if the message type
+                                                                       // bytes should be included here or not. The BOLTs have now
+                                                                       // been updated to indicate that they *are* included, but many
+                                                                       // nodes still send messages without the type bytes, so we
+                                                                       // support both here.
+                                                                       // TODO: Switch to hard require the type prefix, as the current
+                                                                       // permissiveness introduces the (although small) possibility
+                                                                       // that we fail to decode legitimate channel updates that
+                                                                       // happen to start with ChannelUpdate::TYPE, i.e., [0x01, 0x02].
+                                                                       if update_slice.len() > 2 && update_slice[0..2] == msgs::ChannelUpdate::TYPE.to_be_bytes() {
+                                                                               update_slice = &update_slice[2..];
+                                                                       } else {
+                                                                               log_trace!(logger, "Failure provided features a channel update without type prefix. Deprecated, but allowing for now.");
+                                                                       }
                                                                        if let Ok(chan_update) = msgs::ChannelUpdate::read(&mut Cursor::new(&update_slice)) {
                                                                                // if channel_update should NOT have caused the failure:
                                                                                // MAY treat the channel_update as invalid.
@@ -425,7 +451,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
                                                                                if is_chan_update_invalid {
                                                                                        // This probably indicates the node which forwarded
                                                                                        // to the node in question corrupted something.
-                                                                                       network_update = Some(NetworkUpdate::ChannelClosed {
+                                                                                       network_update = Some(NetworkUpdate::ChannelFailure {
                                                                                                short_channel_id: route_hop.short_channel_id,
                                                                                                is_permanent: true,
                                                                                        });
@@ -434,6 +460,8 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
                                                                                        // short channel id.
                                                                                        if failing_route_hop.short_channel_id == chan_update.contents.short_channel_id {
                                                                                                short_channel_id = Some(failing_route_hop.short_channel_id);
+                                                                                       } else {
+                                                                                               log_info!(logger, "Node provided a channel_update for which it was not authoritative, ignoring.");
                                                                                        }
                                                                                        network_update = Some(NetworkUpdate::ChannelUpdateMessage {
                                                                                                msg: chan_update,
@@ -478,10 +506,10 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
 
                                                let (description, title) = errors::get_onion_error_description(error_code);
                                                if debug_field_size > 0 && err_packet.failuremsg.len() >= 4 + debug_field_size {
-                                                       log_warn!(logger, "Onion Error[from {}: {}({:#x}) {}({})] {}", route_hop.pubkey, title, error_code, debug_field, log_bytes!(&err_packet.failuremsg[4..4+debug_field_size]), description);
+                                                       log_info!(logger, "Onion Error[from {}: {}({:#x}) {}({})] {}", route_hop.pubkey, title, error_code, debug_field, log_bytes!(&err_packet.failuremsg[4..4+debug_field_size]), description);
                                                }
                                                else {
-                                                       log_warn!(logger, "Onion Error[from {}: {}({:#x})] {}", route_hop.pubkey, title, error_code, description);
+                                                       log_info!(logger, "Onion Error[from {}: {}({:#x})] {}", route_hop.pubkey, title, error_code, description);
                                                }
                                        } else {
                                                // Useless packet that we can't use but it passed HMAC, so it