]> git.bitcoin.ninja Git - rust-lightning/blobdiff - src/ln/channelmanager.rs
Switch Sha256 to using bitcoin_hashes and our own HKDF
[rust-lightning] / src / ln / channelmanager.rs
index fcb79cdb59dcc74a125fd57ab06d23eb2839b185..28bf4fd7f3906c395d3959b915a8e74c09a4265d 100644 (file)
@@ -14,6 +14,10 @@ use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::network::constants::Network;
 use bitcoin::util::hash::{BitcoinHash, Sha256dHash};
 
+use bitcoin_hashes::{Hash, HashEngine};
+use bitcoin_hashes::hmac::{Hmac, HmacEngine};
+use bitcoin_hashes::sha256::Hash as Sha256;
+
 use secp256k1::key::{SecretKey,PublicKey};
 use secp256k1::{Secp256k1,Message};
 use secp256k1::ecdh::SharedSecret;
@@ -29,7 +33,6 @@ use ln::msgs::{ChannelMessageHandler, DecodeError, HandleError};
 use chain::keysinterface::KeysInterface;
 use util::config::UserConfig;
 use util::{byte_utils, events, internal_traits, rng};
-use util::sha2::Sha256;
 use util::ser::{Readable, ReadableArgs, Writeable, Writer};
 use util::chacha20poly1305rfc::ChaCha20;
 use util::logger::Logger;
@@ -37,9 +40,6 @@ use util::errors::APIError;
 use util::errors;
 
 use crypto;
-use crypto::mac::{Mac,MacResult};
-use crypto::hmac::Hmac;
-use crypto::digest::Digest;
 use crypto::symmetriccipher::SynchronousStreamCipher;
 
 use std::{cmp, ptr, mem};
@@ -212,16 +212,6 @@ impl MsgHandleErrInternal {
        }
 }
 
-/// Pass to fail_htlc_backwwards to indicate the reason to fail the payment
-/// after a PaymentReceived event.
-#[derive(PartialEq)]
-pub enum PaymentFailReason {
-       /// Indicate the preimage for payment_hash is not known after a PaymentReceived event
-       PreimageUnknown,
-       /// Indicate the payment amount is incorrect ( received is < expected or > 2*expected ) after a PaymentReceived event
-       AmountMismatch,
-}
-
 /// We hold back HTLCs we intend to relay for a random interval in the range (this, 5*this). This
 /// provides some limited amount of privacy. Ideally this would range from somewhere like 1 second
 /// to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly. We could
@@ -732,39 +722,31 @@ impl ChannelManager {
        fn gen_rho_mu_from_shared_secret(shared_secret: &[u8]) -> ([u8; 32], [u8; 32]) {
                assert_eq!(shared_secret.len(), 32);
                ({
-                       let mut hmac = Hmac::new(Sha256::new(), &[0x72, 0x68, 0x6f]); // rho
+                       let mut hmac = HmacEngine::<Sha256>::new(&[0x72, 0x68, 0x6f]); // rho
                        hmac.input(&shared_secret[..]);
-                       let mut res = [0; 32];
-                       hmac.raw_result(&mut res);
-                       res
+                       Hmac::from_engine(hmac).into_inner()
                },
                {
-                       let mut hmac = Hmac::new(Sha256::new(), &[0x6d, 0x75]); // mu
+                       let mut hmac = HmacEngine::<Sha256>::new(&[0x6d, 0x75]); // mu
                        hmac.input(&shared_secret[..]);
-                       let mut res = [0; 32];
-                       hmac.raw_result(&mut res);
-                       res
+                       Hmac::from_engine(hmac).into_inner()
                })
        }
 
        #[inline]
        fn gen_um_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
                assert_eq!(shared_secret.len(), 32);
-               let mut hmac = Hmac::new(Sha256::new(), &[0x75, 0x6d]); // um
+               let mut hmac = HmacEngine::<Sha256>::new(&[0x75, 0x6d]); // um
                hmac.input(&shared_secret[..]);
-               let mut res = [0; 32];
-               hmac.raw_result(&mut res);
-               res
+               Hmac::from_engine(hmac).into_inner()
        }
 
        #[inline]
        fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
                assert_eq!(shared_secret.len(), 32);
-               let mut hmac = Hmac::new(Sha256::new(), &[0x61, 0x6d, 0x6d, 0x61, 0x67]); // ammag
+               let mut hmac = HmacEngine::<Sha256>::new(&[0x61, 0x6d, 0x6d, 0x61, 0x67]); // ammag
                hmac.input(&shared_secret[..]);
-               let mut res = [0; 32];
-               hmac.raw_result(&mut res);
-               res
+               Hmac::from_engine(hmac).into_inner()
        }
 
        // can only fail if an intermediary hop has an invalid public key or session_priv is invalid
@@ -776,11 +758,10 @@ impl ChannelManager {
                for hop in route.hops.iter() {
                        let shared_secret = SharedSecret::new(secp_ctx, &hop.pubkey, &blinded_priv);
 
-                       let mut sha = Sha256::new();
+                       let mut sha = Sha256::engine();
                        sha.input(&blinded_pub.serialize()[..]);
                        sha.input(&shared_secret[..]);
-                       let mut blinding_factor = [0u8; 32];
-                       sha.result(&mut blinding_factor);
+                       let blinding_factor = Sha256::from_engine(sha).into_inner();
 
                        let ephemeral_pubkey = blinded_pub;
 
@@ -906,10 +887,10 @@ impl ChannelManager {
                                packet_data[20*65 - filler.len()..20*65].copy_from_slice(&filler[..]);
                        }
 
-                       let mut hmac = Hmac::new(Sha256::new(), &keys.mu);
+                       let mut hmac = HmacEngine::<Sha256>::new(&keys.mu);
                        hmac.input(&packet_data);
                        hmac.input(&associated_data.0[..]);
-                       hmac.raw_result(&mut hmac_res);
+                       hmac_res = Hmac::from_engine(hmac).into_inner();
                }
 
                msgs::OnionPacket{
@@ -958,9 +939,9 @@ impl ChannelManager {
                        pad: pad,
                };
 
-               let mut hmac = Hmac::new(Sha256::new(), &um);
+               let mut hmac = HmacEngine::<Sha256>::new(&um);
                hmac.input(&packet.encode()[32..]);
-               hmac.raw_result(&mut packet.hmac);
+               packet.hmac = Hmac::from_engine(hmac).into_inner();
 
                packet
        }
@@ -976,14 +957,10 @@ impl ChannelManager {
                        ($msg: expr, $err_code: expr) => {
                                {
                                        log_info!(self, "Failed to accept/forward incoming HTLC: {}", $msg);
-                                       let mut sha256_of_onion = [0; 32];
-                                       let mut sha = Sha256::new();
-                                       sha.input(&msg.onion_routing_packet.hop_data);
-                                       sha.result(&mut sha256_of_onion);
                                        return (PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
                                                channel_id: msg.channel_id,
                                                htlc_id: msg.htlc_id,
-                                               sha256_of_onion,
+                                               sha256_of_onion: Sha256::hash(&msg.onion_routing_packet.hop_data).into_inner(),
                                                failure_code: $err_code,
                                        })), self.channel_state.lock().unwrap());
                                }
@@ -1011,10 +988,11 @@ impl ChannelManager {
                        return_malformed_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4);
                }
 
-               let mut hmac = Hmac::new(Sha256::new(), &mu);
+
+               let mut hmac = HmacEngine::<Sha256>::new(&mu);
                hmac.input(&msg.onion_routing_packet.hop_data);
                hmac.input(&msg.payment_hash.0[..]);
-               if hmac.result() != MacResult::new(&msg.onion_routing_packet.hmac) {
+               if !crypto::util::fixed_time_eq(&Hmac::from_engine(hmac).into_inner(), &msg.onion_routing_packet.hmac) {
                        return_malformed_err!("HMAC Check failed", 0x8000 | 0x4000 | 5);
                }
 
@@ -1087,12 +1065,10 @@ impl ChannelManager {
                                let mut new_pubkey = msg.onion_routing_packet.public_key.unwrap();
 
                                let blinding_factor = {
-                                       let mut sha = Sha256::new();
+                                       let mut sha = Sha256::engine();
                                        sha.input(&new_pubkey.serialize()[..]);
                                        sha.input(&shared_secret);
-                                       let mut res = [0u8; 32];
-                                       sha.result(&mut res);
-                                       SecretKey::from_slice(&self.secp_ctx, &res).expect("SHA-256 is broken?")
+                                       SecretKey::from_slice(&self.secp_ctx, &Sha256::from_engine(sha).into_inner()).expect("SHA-256 is broken?")
                                };
 
                                let public_key = if let Err(e) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor) {
@@ -1530,8 +1506,11 @@ impl ChannelManager {
                events.append(&mut new_events);
        }
 
-       /// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect after a PaymentReceived event.
-       pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash, reason: PaymentFailReason) -> bool {
+       /// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect
+       /// after a PaymentReceived event.
+       /// expected_value is the value you expected the payment to be for (not the amount it actually
+       /// was for from the PaymentReceived event).
+       pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash, expected_value: u64) -> bool {
                let _ = self.total_consistency_lock.read().unwrap();
 
                let mut channel_state = Some(self.channel_state.lock().unwrap());
@@ -1539,7 +1518,9 @@ impl ChannelManager {
                if let Some(mut sources) = removed_source {
                        for htlc_with_hash in sources.drain(..) {
                                if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
-                               self.fail_htlc_backwards_internal(channel_state.take().unwrap(), HTLCSource::PreviousHopData(htlc_with_hash), payment_hash, HTLCFailReason::Reason { failure_code: if reason == PaymentFailReason::PreimageUnknown {0x4000 | 15} else {0x4000 | 16}, data: Vec::new() });
+                               self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
+                                               HTLCSource::PreviousHopData(htlc_with_hash), payment_hash,
+                                               HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: byte_utils::be64_to_array(expected_value).to_vec() });
                        }
                        true
                } else { false }
@@ -1657,10 +1638,7 @@ impl ChannelManager {
        ///
        /// May panic if called except in response to a PaymentReceived event.
        pub fn claim_funds(&self, payment_preimage: PaymentPreimage) -> bool {
-               let mut sha = Sha256::new();
-               sha.input(&payment_preimage.0[..]);
-               let mut payment_hash = PaymentHash([0; 32]);
-               sha.result(&mut payment_hash.0[..]);
+               let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
 
                let _ = self.total_consistency_lock.read().unwrap();
 
@@ -2161,12 +2139,10 @@ impl ChannelManager {
 
                                if let Ok(err_packet) = msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet_decrypted)) {
                                        let um = ChannelManager::gen_um_from_shared_secret(&shared_secret[..]);
-                                       let mut hmac = Hmac::new(Sha256::new(), &um);
+                                       let mut hmac = HmacEngine::<Sha256>::new(&um);
                                        hmac.input(&err_packet.encode()[32..]);
-                                       let mut calc_tag = [0u8; 32];
-                                       hmac.raw_result(&mut calc_tag);
 
-                                       if crypto::util::fixed_time_eq(&calc_tag, &err_packet.hmac) {
+                                       if crypto::util::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 PERM: u16 = 0x4000;
                                                        const NODE: u16 = 0x2000;
@@ -3363,12 +3339,12 @@ mod tests {
        use chain::keysinterface::{KeysInterface, SpendableOutputDescriptor};
        use chain::keysinterface;
        use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC};
-       use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,OnionKeys,PaymentFailReason,RAACommitmentOrder, PaymentPreimage, PaymentHash};
+       use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,OnionKeys,RAACommitmentOrder, PaymentPreimage, PaymentHash};
        use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS, ManyChannelMonitor};
        use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT};
        use ln::router::{Route, RouteHop, Router};
        use ln::msgs;
-       use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
+       use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler,HTLCFailChannelUpdate};
        use util::test_utils;
        use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
        use util::errors::APIError;
@@ -3387,14 +3363,14 @@ mod tests {
        use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::network::constants::Network;
 
+       use bitcoin_hashes::sha256::Hash as Sha256;
+       use bitcoin_hashes::Hash;
+
        use hex;
 
        use secp256k1::{Secp256k1, Message};
        use secp256k1::key::{PublicKey,SecretKey};
 
-       use crypto::sha2::Sha256;
-       use crypto::digest::Digest;
-
        use rand::{thread_rng,Rng};
 
        use std::cell::RefCell;
@@ -3570,6 +3546,7 @@ mod tests {
                chain_monitor: Arc<chaininterface::ChainWatchInterfaceUtil>,
                tx_broadcaster: Arc<test_utils::TestBroadcaster>,
                chan_monitor: Arc<test_utils::TestChannelMonitor>,
+               keys_manager: Arc<test_utils::TestKeysInterface>,
                node: Arc<ChannelManager>,
                router: Router,
                node_seed: [u8; 32],
@@ -3777,6 +3754,8 @@ mod tests {
                let as_update = match events_8[0] {
                        MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                                assert!(*announcement == *msg);
+                               assert_eq!(update_msg.contents.short_channel_id, announcement.contents.short_channel_id);
+                               assert_eq!(update_msg.contents.short_channel_id, bs_update.contents.short_channel_id);
                                update_msg
                        },
                        _ => panic!("Unexpected event"),
@@ -4032,10 +4011,7 @@ mod tests {
                        {
                                let payment_preimage = PaymentPreimage([*$node.network_payment_count.borrow(); 32]);
                                *$node.network_payment_count.borrow_mut() += 1;
-                               let mut payment_hash = PaymentHash([0; 32]);
-                               let mut sha = Sha256::new();
-                               sha.input(&payment_preimage.0[..]);
-                               sha.result(&mut payment_hash.0[..]);
+                               let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
                                (payment_preimage, payment_hash)
                        }
                }
@@ -4218,7 +4194,7 @@ mod tests {
        }
 
        fn fail_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_hash: PaymentHash) {
-               assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash, PaymentFailReason::PreimageUnknown));
+               assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash, 0));
                check_added_monitors!(expected_route.last().unwrap(), 1);
 
                let mut next_msgs: Option<(msgs::UpdateFailHTLC, msgs::CommitmentSigned)> = None;
@@ -4301,14 +4277,14 @@ mod tests {
                        let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())});
                        let mut seed = [0; 32];
                        rng.fill_bytes(&mut seed);
-                       let keys_manager = Arc::new(keysinterface::KeysManager::new(&seed, Network::Testnet, Arc::clone(&logger)));
+                       let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet, Arc::clone(&logger)));
                        let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone(), logger.clone()));
                        let mut config = UserConfig::new();
                        config.channel_options.announced_channel = true;
                        config.channel_limits.force_announced_channel_preference = false;
                        let node = ChannelManager::new(Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger), keys_manager.clone(), config).unwrap();
                        let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), chain_monitor.clone(), Arc::clone(&logger));
-                       nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router, node_seed: seed,
+                       nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router, keys_manager, node_seed: seed,
                                network_payment_count: payment_count.clone(),
                                network_chan_count: chan_count.clone(),
                        });
@@ -6345,7 +6321,7 @@ mod tests {
                // Brodacast legit commitment tx from C on B's chain
                let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
                check_spends!(commitment_tx[0], chan_2.3.clone());
-               nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::PreimageUnknown);
+               nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
                {
                        let mut added_monitors = nodes[2].chan_monitor.added_monitors.lock().unwrap();
                        assert_eq!(added_monitors.len(), 1);
@@ -6530,7 +6506,7 @@ mod tests {
                let (_, second_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
                let (_, third_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
 
-               assert!(nodes[2].node.fail_htlc_backwards(&first_payment_hash, PaymentFailReason::PreimageUnknown));
+               assert!(nodes[2].node.fail_htlc_backwards(&first_payment_hash, 0));
                check_added_monitors!(nodes[2], 1);
                let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
                assert!(updates.update_add_htlcs.is_empty());
@@ -6542,7 +6518,7 @@ mod tests {
                let bs_raa = commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false, true, false, true);
                // Drop the last RAA from 3 -> 2
 
-               assert!(nodes[2].node.fail_htlc_backwards(&second_payment_hash, PaymentFailReason::PreimageUnknown));
+               assert!(nodes[2].node.fail_htlc_backwards(&second_payment_hash, 0));
                check_added_monitors!(nodes[2], 1);
                let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
                assert!(updates.update_add_htlcs.is_empty());
@@ -6558,7 +6534,7 @@ mod tests {
                nodes[2].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &as_raa).unwrap();
                check_added_monitors!(nodes[2], 1);
 
-               assert!(nodes[2].node.fail_htlc_backwards(&third_payment_hash, PaymentFailReason::PreimageUnknown));
+               assert!(nodes[2].node.fail_htlc_backwards(&third_payment_hash, 0));
                check_added_monitors!(nodes[2], 1);
                let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
                assert!(updates.update_add_htlcs.is_empty());
@@ -8153,7 +8129,7 @@ mod tests {
                let (_, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
 
                // Fail the payment backwards, failing the monitor update on nodes[1]'s receipt of the RAA
-               assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1, PaymentFailReason::PreimageUnknown));
+               assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1, 0));
                check_added_monitors!(nodes[2], 1);
 
                let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
@@ -9461,4 +9437,411 @@ mod tests {
                assert_eq!(spend_txn.len(), 1);
                check_spends!(spend_txn[0], closing_tx);
        }
+
+       fn run_onion_failure_test<F1,F2>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, callback_msg: F1, callback_node: F2, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<HTLCFailChannelUpdate>)
+               where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC),
+                                       F2: FnMut(),
+       {
+               run_onion_failure_test_with_fail_intercept(_name, test_case, nodes, route, payment_hash, callback_msg, |_|{}, callback_node, expected_retryable, expected_error_code, expected_channel_update);
+       }
+
+       // test_case
+       // 0: node1 fail backward
+       // 1: final node fail backward
+       // 2: payment completed but the user reject the payment
+       // 3: final node fail backward (but tamper onion payloads from node0)
+       // 100: trigger error in the intermediate node and tamper returnning fail_htlc
+       // 200: trigger error in the final node and tamper returnning fail_htlc
+       fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, mut callback_msg: F1, mut callback_fail: F2, mut callback_node: F3, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<HTLCFailChannelUpdate>)
+               where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC),
+                                       F2: for <'a> FnMut(&'a mut msgs::UpdateFailHTLC),
+                                       F3: FnMut(),
+       {
+               use ln::msgs::HTLCFailChannelUpdate;
+
+               // reset block height
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+               for ix in 0..nodes.len() {
+                       nodes[ix].chain_monitor.block_connected_checked(&header, 1, &Vec::new()[..], &[0; 0]);
+               }
+
+               macro_rules! expect_event {
+                       ($node: expr, $event_type: path) => {{
+                               let events = $node.node.get_and_clear_pending_events();
+                               assert_eq!(events.len(), 1);
+                               match events[0] {
+                                       $event_type { .. } => {},
+                                       _ => panic!("Unexpected event"),
+                               }
+                       }}
+               }
+
+               macro_rules! expect_htlc_forward {
+                       ($node: expr) => {{
+                               expect_event!($node, Event::PendingHTLCsForwardable);
+                               $node.node.channel_state.lock().unwrap().next_forward = Instant::now();
+                               $node.node.process_pending_htlc_forwards();
+                       }}
+               }
+
+               // 0 ~~> 2 send payment
+               nodes[0].node.send_payment(route.clone(), payment_hash.clone()).unwrap();
+               check_added_monitors!(nodes[0], 1);
+               let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+               // temper update_add (0 => 1)
+               let mut update_add_0 = update_0.update_add_htlcs[0].clone();
+               if test_case == 0 || test_case == 3 || test_case == 100 {
+                       callback_msg(&mut update_add_0);
+                       callback_node();
+               }
+               // 0 => 1 update_add & CS
+               nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add_0).unwrap();
+               commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
+
+               let update_1_0 = match test_case {
+                       0|100 => { // intermediate node failure; fail backward to 0
+                               let update_1_0 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+                               assert!(update_1_0.update_fail_htlcs.len()+update_1_0.update_fail_malformed_htlcs.len()==1 && (update_1_0.update_fail_htlcs.len()==1 || update_1_0.update_fail_malformed_htlcs.len()==1));
+                               update_1_0
+                       },
+                       1|2|3|200 => { // final node failure; forwarding to 2
+                               assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
+                               // forwarding on 1
+                               if test_case != 200 {
+                                       callback_node();
+                               }
+                               expect_htlc_forward!(&nodes[1]);
+
+                               let update_1 = get_htlc_update_msgs!(nodes[1], nodes[2].node.get_our_node_id());
+                               check_added_monitors!(&nodes[1], 1);
+                               assert_eq!(update_1.update_add_htlcs.len(), 1);
+                               // tamper update_add (1 => 2)
+                               let mut update_add_1 = update_1.update_add_htlcs[0].clone();
+                               if test_case != 3 && test_case != 200 {
+                                       callback_msg(&mut update_add_1);
+                               }
+
+                               // 1 => 2
+                               nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &update_add_1).unwrap();
+                               commitment_signed_dance!(nodes[2], nodes[1], update_1.commitment_signed, false, true);
+
+                               if test_case == 2 || test_case == 200 {
+                                       expect_htlc_forward!(&nodes[2]);
+                                       expect_event!(&nodes[2], Event::PaymentReceived);
+                                       callback_node();
+                               }
+
+                               let update_2_1 = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
+                               if test_case == 2 || test_case == 200 {
+                                       check_added_monitors!(&nodes[2], 1);
+                               }
+                               assert!(update_2_1.update_fail_htlcs.len() == 1);
+
+                               let mut fail_msg = update_2_1.update_fail_htlcs[0].clone();
+                               if test_case == 200 {
+                                       callback_fail(&mut fail_msg);
+                               }
+
+                               // 2 => 1
+                               nodes[1].node.handle_update_fail_htlc(&nodes[2].node.get_our_node_id(), &fail_msg).unwrap();
+                               commitment_signed_dance!(nodes[1], nodes[2], update_2_1.commitment_signed, true, true);
+
+                               // backward fail on 1
+                               let update_1_0 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+                               assert!(update_1_0.update_fail_htlcs.len() == 1);
+                               update_1_0
+                       },
+                       _ => unreachable!(),
+               };
+
+               // 1 => 0 commitment_signed_dance
+               if update_1_0.update_fail_htlcs.len() > 0 {
+                       let mut fail_msg = update_1_0.update_fail_htlcs[0].clone();
+                       if test_case == 100 {
+                               callback_fail(&mut fail_msg);
+                       }
+                       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg).unwrap();
+               } else {
+                       nodes[0].node.handle_update_fail_malformed_htlc(&nodes[1].node.get_our_node_id(), &update_1_0.update_fail_malformed_htlcs[0]).unwrap();
+               };
+
+               commitment_signed_dance!(nodes[0], nodes[1], update_1_0.commitment_signed, false, true);
+
+               let events = nodes[0].node.get_and_clear_pending_events();
+               assert_eq!(events.len(), 1);
+               if let &Event::PaymentFailed { payment_hash:_, ref rejected_by_dest, ref error_code } = &events[0] {
+                       assert_eq!(*rejected_by_dest, !expected_retryable);
+                       assert_eq!(*error_code, expected_error_code);
+               } else {
+                       panic!("Uexpected event");
+               }
+
+               let events = nodes[0].node.get_and_clear_pending_msg_events();
+               if expected_channel_update.is_some() {
+                       assert_eq!(events.len(), 1);
+                       match events[0] {
+                               MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => {
+                                       match update {
+                                               &HTLCFailChannelUpdate::ChannelUpdateMessage { .. } => {
+                                                       if let HTLCFailChannelUpdate::ChannelUpdateMessage { .. } = expected_channel_update.unwrap() {} else {
+                                                               panic!("channel_update not found!");
+                                                       }
+                                               },
+                                               &HTLCFailChannelUpdate::ChannelClosed { ref short_channel_id, ref is_permanent } => {
+                                                       if let HTLCFailChannelUpdate::ChannelClosed { short_channel_id: ref expected_short_channel_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() {
+                                                               assert!(*short_channel_id == *expected_short_channel_id);
+                                                               assert!(*is_permanent == *expected_is_permanent);
+                                                       } else {
+                                                               panic!("Unexpected message event");
+                                                       }
+                                               },
+                                               &HTLCFailChannelUpdate::NodeFailure { ref node_id, ref is_permanent } => {
+                                                       if let HTLCFailChannelUpdate::NodeFailure { node_id: ref expected_node_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() {
+                                                               assert!(*node_id == *expected_node_id);
+                                                               assert!(*is_permanent == *expected_is_permanent);
+                                                       } else {
+                                                               panic!("Unexpected message event");
+                                                       }
+                                               },
+                                       }
+                               },
+                               _ => panic!("Unexpected message event"),
+                       }
+               } else {
+                       assert_eq!(events.len(), 0);
+               }
+       }
+
+       impl msgs::ChannelUpdate {
+               fn dummy() -> msgs::ChannelUpdate {
+                       use secp256k1::ffi::Signature as FFISignature;
+                       use secp256k1::Signature;
+                       msgs::ChannelUpdate {
+                               signature: Signature::from(FFISignature::new()),
+                               contents: msgs::UnsignedChannelUpdate {
+                                       chain_hash: Sha256dHash::from_data(&vec![0u8][..]),
+                                       short_channel_id: 0,
+                                       timestamp: 0,
+                                       flags: 0,
+                                       cltv_expiry_delta: 0,
+                                       htlc_minimum_msat: 0,
+                                       fee_base_msat: 0,
+                                       fee_proportional_millionths: 0,
+                                       excess_data: vec![],
+                               }
+                       }
+               }
+       }
+
+       #[test]
+       fn test_onion_failure() {
+               use ln::msgs::ChannelUpdate;
+               use ln::channelmanager::CLTV_FAR_FAR_AWAY;
+               use secp256k1;
+
+               const BADONION: u16 = 0x8000;
+               const PERM: u16 = 0x4000;
+               const NODE: u16 = 0x2000;
+               const UPDATE: u16 = 0x1000;
+
+               let mut nodes = create_network(3);
+               for node in nodes.iter() {
+                       *node.keys_manager.override_session_priv.lock().unwrap() = Some(SecretKey::from_slice(&Secp256k1::without_caps(), &[3; 32]).unwrap());
+               }
+               let channels = [create_announced_chan_between_nodes(&nodes, 0, 1), create_announced_chan_between_nodes(&nodes, 1, 2)];
+               let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
+               let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 40000, TEST_FINAL_CLTV).unwrap();
+               // positve case
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 40000);
+
+               // intermediate node failure
+               run_onion_failure_test("invalid_realm", 0, &nodes, &route, &payment_hash, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       let (mut onion_payloads, _htlc_msat, _htlc_cltv) = ChannelManager::build_onion_payloads(&route, cur_height).unwrap();
+                       onion_payloads[0].realm = 3;
+                       msg.onion_routing_packet = ChannelManager::construct_onion_packet(onion_payloads, onion_keys, &payment_hash);
+               }, ||{}, true, Some(PERM|1), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));//XXX incremented channels idx here
+
+               // final node failure
+               run_onion_failure_test("invalid_realm", 3, &nodes, &route, &payment_hash, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       let (mut onion_payloads, _htlc_msat, _htlc_cltv) = ChannelManager::build_onion_payloads(&route, cur_height).unwrap();
+                       onion_payloads[1].realm = 3;
+                       msg.onion_routing_packet = ChannelManager::construct_onion_packet(onion_payloads, onion_keys, &payment_hash);
+               }, ||{}, false, Some(PERM|1), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
+
+               // the following three with run_onion_failure_test_with_fail_intercept() test only the origin node
+               // receiving simulated fail messages
+               // intermediate node failure
+               run_onion_failure_test_with_fail_intercept("temporary_node_failure", 100, &nodes, &route, &payment_hash, |msg| {
+                       // trigger error
+                       msg.amount_msat -= 1;
+               }, |msg| {
+                       // and tamper returing error message
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], NODE|2, &[0;0]);
+               }, ||{}, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[0].pubkey, is_permanent: false}));
+
+               // final node failure
+               run_onion_failure_test_with_fail_intercept("temporary_node_failure", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| {
+                       // and tamper returing error message
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], NODE|2, &[0;0]);
+               }, ||{
+                       nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
+               }, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: false}));
+
+               // intermediate node failure
+               run_onion_failure_test_with_fail_intercept("permanent_node_failure", 100, &nodes, &route, &payment_hash, |msg| {
+                       msg.amount_msat -= 1;
+               }, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|2, &[0;0]);
+               }, ||{}, true, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[0].pubkey, is_permanent: true}));
+
+               // final node failure
+               run_onion_failure_test_with_fail_intercept("permanent_node_failure", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|2, &[0;0]);
+               }, ||{
+                       nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
+               }, false, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: true}));
+
+               // intermediate node failure
+               run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 100, &nodes, &route, &payment_hash, |msg| {
+                       msg.amount_msat -= 1;
+               }, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|3, &[0;0]);
+               }, ||{
+                       nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
+               }, true, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[0].pubkey, is_permanent: true}));
+
+               // final node failure
+               run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|3, &[0;0]);
+               }, ||{
+                       nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
+               }, false, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: true}));
+
+               run_onion_failure_test("invalid_onion_version", 0, &nodes, &route, &payment_hash, |msg| { msg.onion_routing_packet.version = 1; }, ||{}, true,
+                       Some(BADONION|PERM|4), None);
+
+               run_onion_failure_test("invalid_onion_hmac", 0, &nodes, &route, &payment_hash, |msg| { msg.onion_routing_packet.hmac = [3; 32]; }, ||{}, true,
+                       Some(BADONION|PERM|5), None);
+
+               run_onion_failure_test("invalid_onion_key", 0, &nodes, &route, &payment_hash, |msg| { msg.onion_routing_packet.public_key = Err(secp256k1::Error::InvalidPublicKey);}, ||{}, true,
+                       Some(BADONION|PERM|6), None);
+
+               run_onion_failure_test_with_fail_intercept("temporary_channel_failure", 100, &nodes, &route, &payment_hash, |msg| {
+                       msg.amount_msat -= 1;
+               }, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], UPDATE|7, &ChannelUpdate::dummy().encode_with_len()[..]);
+               }, ||{}, true, Some(UPDATE|7), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
+
+               run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, |msg| {
+                       msg.amount_msat -= 1;
+               }, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|8, &[0;0]);
+                       // short_channel_id from the processing node
+               }, ||{}, true, Some(PERM|8), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
+
+               run_onion_failure_test_with_fail_intercept("required_channel_feature_missing", 100, &nodes, &route, &payment_hash, |msg| {
+                       msg.amount_msat -= 1;
+               }, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|9, &[0;0]);
+                       // short_channel_id from the processing node
+               }, ||{}, true, Some(PERM|9), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
+
+               let mut bogus_route = route.clone();
+               bogus_route.hops[1].short_channel_id -= 1;
+               run_onion_failure_test("unknown_next_peer", 0, &nodes, &bogus_route, &payment_hash, |_| {}, ||{}, true, Some(PERM|10),
+                 Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: bogus_route.hops[1].short_channel_id, is_permanent:true}));
+
+               let amt_to_forward = nodes[1].node.channel_state.lock().unwrap().by_id.get(&channels[1].2).unwrap().get_their_htlc_minimum_msat() - 1;
+               let mut bogus_route = route.clone();
+               let route_len = bogus_route.hops.len();
+               bogus_route.hops[route_len-1].fee_msat = amt_to_forward;
+               run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, |_| {}, ||{}, true, Some(UPDATE|11), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
+
+               //TODO: with new config API, we will be able to generate both valid and
+               //invalid channel_update cases.
+               run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, |msg| {
+                       msg.amount_msat -= 1;
+               }, || {}, true, Some(UPDATE|12), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
+
+               run_onion_failure_test("incorrect_cltv_expiry", 0, &nodes, &route, &payment_hash, |msg| {
+                       // need to violate: cltv_expiry - cltv_expiry_delta >= outgoing_cltv_value
+                       msg.cltv_expiry -= 1;
+               }, || {}, true, Some(UPDATE|13), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
+
+               run_onion_failure_test("expiry_too_soon", 0, &nodes, &route, &payment_hash, |msg| {
+                       let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - HTLC_FAIL_TIMEOUT_BLOCKS + 1;
+                       let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[1].chain_monitor.block_connected_checked(&header, height, &Vec::new()[..], &[0; 0]);
+               }, ||{}, true, Some(UPDATE|14), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
+
+               run_onion_failure_test("unknown_payment_hash", 2, &nodes, &route, &payment_hash, |_| {}, || {
+                       nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
+               }, false, Some(PERM|15), None);
+
+               run_onion_failure_test("final_expiry_too_soon", 1, &nodes, &route, &payment_hash, |msg| {
+                       let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - HTLC_FAIL_TIMEOUT_BLOCKS + 1;
+                       let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[2].chain_monitor.block_connected_checked(&header, height, &Vec::new()[..], &[0; 0]);
+               }, || {}, true, Some(17), None);
+
+               run_onion_failure_test("final_incorrect_cltv_expiry", 1, &nodes, &route, &payment_hash, |_| {}, || {
+                       for (_, mut pending_forwards) in nodes[1].node.channel_state.lock().unwrap().borrow_parts().forward_htlcs.iter_mut() {
+                               for f in pending_forwards.iter_mut() {
+                                       f.forward_info.outgoing_cltv_value += 1;
+                               }
+                       }
+               }, true, Some(18), None);
+
+               run_onion_failure_test("final_incorrect_htlc_amount", 1, &nodes, &route, &payment_hash, |_| {}, || {
+                       // violate amt_to_forward > msg.amount_msat
+                       for (_, mut pending_forwards) in nodes[1].node.channel_state.lock().unwrap().borrow_parts().forward_htlcs.iter_mut() {
+                               for f in pending_forwards.iter_mut() {
+                                       f.forward_info.amt_to_forward -= 1;
+                               }
+                       }
+               }, true, Some(19), None);
+
+               run_onion_failure_test("channel_disabled", 0, &nodes, &route, &payment_hash, |_| {}, || {
+                       // disconnect event to the channel between nodes[1] ~ nodes[2]
+                       nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
+                       nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+               }, true, Some(UPDATE|20), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
+               reconnect_nodes(&nodes[1], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
+
+               run_onion_failure_test("expiry_too_far", 0, &nodes, &route, &payment_hash, |msg| {
+                       let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap();
+                       let mut route = route.clone();
+                       let height = 1;
+                       route.hops[1].cltv_expiry_delta += CLTV_FAR_FAR_AWAY + route.hops[0].cltv_expiry_delta + 1;
+                       let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+                       let (onion_payloads, _, htlc_cltv) = ChannelManager::build_onion_payloads(&route, height).unwrap();
+                       let onion_packet = ChannelManager::construct_onion_packet(onion_payloads, onion_keys, &payment_hash);
+                       msg.cltv_expiry = htlc_cltv;
+                       msg.onion_routing_packet = onion_packet;
+               }, ||{}, true, Some(21), None);
+       }
 }