Merge pull request #441 from TheBlueMatt/2020-01-mpp
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Wed, 15 Apr 2020 01:36:44 +0000 (01:36 +0000)
committerGitHub <noreply@github.com>
Wed, 15 Apr 2020 01:36:44 +0000 (01:36 +0000)
Multi-Path Payments

14 files changed:
fuzz/src/chanmon_consistency.rs
fuzz/src/full_stack.rs
lightning/src/ln/chanmon_update_fail_tests.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/features.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/msgs.rs
lightning/src/ln/onion_utils.rs
lightning/src/ln/reorg_tests.rs
lightning/src/ln/router.rs
lightning/src/util/events.rs
lightning/src/util/macro_logger.rs
lightning/src/util/ser.rs

index bcacae883d3d91fc5a9f7882c2859a07adc22e3e..3d14808b0160471ae04f6eb11ef677ada8a96393 100644 (file)
@@ -27,7 +27,7 @@ use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,C
 use lightning::chain::keysinterface::{KeysInterface, InMemoryChannelKeys};
 use lightning::ln::channelmonitor;
 use lightning::ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, HTLCUpdate};
-use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, ChannelManagerReadArgs};
+use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, ChannelManagerReadArgs};
 use lightning::ln::router::{Route, RouteHop};
 use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, UpdateAddHTLC, Init};
@@ -408,16 +408,16 @@ pub fn do_test(data: &[u8]) {
                        ($source: expr, $dest: expr) => { {
                                let payment_hash = Sha256::hash(&[payment_id; 1]);
                                payment_id = payment_id.wrapping_add(1);
-                               if let Err(_) = $source.send_payment(Route {
-                                       hops: vec![RouteHop {
+                               if let Err(_) = $source.send_payment(&Route {
+                                       paths: vec![vec![RouteHop {
                                                pubkey: $dest.0.get_our_node_id(),
                                                node_features: NodeFeatures::empty(),
                                                short_channel_id: $dest.1,
                                                channel_features: ChannelFeatures::empty(),
                                                fee_msat: 5000000,
                                                cltv_expiry_delta: 200,
-                                       }],
-                               }, PaymentHash(payment_hash.into_inner())) {
+                                       }]],
+                               }, PaymentHash(payment_hash.into_inner()), &None) {
                                        // Probably ran out of funds
                                        test_return!();
                                }
@@ -425,8 +425,8 @@ pub fn do_test(data: &[u8]) {
                        ($source: expr, $middle: expr, $dest: expr) => { {
                                let payment_hash = Sha256::hash(&[payment_id; 1]);
                                payment_id = payment_id.wrapping_add(1);
-                               if let Err(_) = $source.send_payment(Route {
-                                       hops: vec![RouteHop {
+                               if let Err(_) = $source.send_payment(&Route {
+                                       paths: vec![vec![RouteHop {
                                                pubkey: $middle.0.get_our_node_id(),
                                                node_features: NodeFeatures::empty(),
                                                short_channel_id: $middle.1,
@@ -440,8 +440,50 @@ pub fn do_test(data: &[u8]) {
                                                channel_features: ChannelFeatures::empty(),
                                                fee_msat: 5000000,
                                                cltv_expiry_delta: 200,
-                                       }],
-                               }, PaymentHash(payment_hash.into_inner())) {
+                                       }]],
+                               }, PaymentHash(payment_hash.into_inner()), &None) {
+                                       // Probably ran out of funds
+                                       test_return!();
+                               }
+                       } }
+               }
+               macro_rules! send_payment_with_secret {
+                       ($source: expr, $middle: expr, $dest: expr) => { {
+                               let payment_hash = Sha256::hash(&[payment_id; 1]);
+                               payment_id = payment_id.wrapping_add(1);
+                               let payment_secret = Sha256::hash(&[payment_id; 1]);
+                               payment_id = payment_id.wrapping_add(1);
+                               if let Err(_) = $source.send_payment(&Route {
+                                       paths: vec![vec![RouteHop {
+                                               pubkey: $middle.0.get_our_node_id(),
+                                               node_features: NodeFeatures::empty(),
+                                               short_channel_id: $middle.1,
+                                               channel_features: ChannelFeatures::empty(),
+                                               fee_msat: 50000,
+                                               cltv_expiry_delta: 100,
+                                       },RouteHop {
+                                               pubkey: $dest.0.get_our_node_id(),
+                                               node_features: NodeFeatures::empty(),
+                                               short_channel_id: $dest.1,
+                                               channel_features: ChannelFeatures::empty(),
+                                               fee_msat: 5000000,
+                                               cltv_expiry_delta: 200,
+                                       }],vec![RouteHop {
+                                               pubkey: $middle.0.get_our_node_id(),
+                                               node_features: NodeFeatures::empty(),
+                                               short_channel_id: $middle.1,
+                                               channel_features: ChannelFeatures::empty(),
+                                               fee_msat: 50000,
+                                               cltv_expiry_delta: 100,
+                                       },RouteHop {
+                                               pubkey: $dest.0.get_our_node_id(),
+                                               node_features: NodeFeatures::empty(),
+                                               short_channel_id: $dest.1,
+                                               channel_features: ChannelFeatures::empty(),
+                                               fee_msat: 5000000,
+                                               cltv_expiry_delta: 200,
+                                       }]],
+                               }, PaymentHash(payment_hash.into_inner()), &Some(PaymentSecret(payment_secret.into_inner()))) {
                                        // Probably ran out of funds
                                        test_return!();
                                }
@@ -599,12 +641,12 @@ pub fn do_test(data: &[u8]) {
                                });
                                for event in events.drain(..) {
                                        match event {
-                                               events::Event::PaymentReceived { payment_hash, .. } => {
+                                               events::Event::PaymentReceived { payment_hash, payment_secret, .. } => {
                                                        if claim_set.insert(payment_hash.0) {
                                                                if $fail {
-                                                                       assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
+                                                                       assert!(nodes[$node].fail_htlc_backwards(&payment_hash, &payment_secret));
                                                                } else {
-                                                                       assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), 5_000_000));
+                                                                       assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), &payment_secret, 5_000_000));
                                                                }
                                                        }
                                                },
@@ -734,6 +776,8 @@ pub fn do_test(data: &[u8]) {
                                nodes[2] = node_c.clone();
                                monitor_c = new_monitor_c;
                        },
+                       0x22 => send_payment_with_secret!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)),
+                       0x23 => send_payment_with_secret!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)),
                        // 0x24 defined above
                        _ => test_return!(),
                }
index 3ae4e56b5f1903093d621d6f91327fcc58d79b5f..be2e0401bdf664cf9a55aceed33ec7d205259c90 100644 (file)
@@ -22,7 +22,7 @@ use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,C
 use lightning::chain::transaction::OutPoint;
 use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface};
 use lightning::ln::channelmonitor;
-use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage};
+use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret};
 use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
 use lightning::ln::router::Router;
 use lightning::util::events::{EventsProvider,Event};
@@ -343,7 +343,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        }, our_network_key, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0], Arc::clone(&logger)));
 
        let mut should_forward = false;
-       let mut payments_received: Vec<(PaymentHash, u64)> = Vec::new();
+       let mut payments_received: Vec<(PaymentHash, Option<PaymentSecret>, u64)> = Vec::new();
        let mut payments_sent = 0;
        let mut pending_funding_generation: Vec<([u8; 32], u64, Script)> = Vec::new();
        let mut pending_funding_signatures = HashMap::new();
@@ -401,7 +401,28 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                sha.input(&payment_hash.0[..]);
                                payment_hash.0 = Sha256::from_engine(sha).into_inner();
                                payments_sent += 1;
-                               match channelmanager.send_payment(route, payment_hash) {
+                               match channelmanager.send_payment(&route, payment_hash, &None) {
+                                       Ok(_) => {},
+                                       Err(_) => return,
+                               }
+                       },
+                       15 => {
+                               let value = slice_to_be24(get_slice!(3)) as u64;
+                               let mut route = match router.get_route(&get_pubkey!(), None, &Vec::new(), value, 42) {
+                                       Ok(route) => route,
+                                       Err(_) => return,
+                               };
+                               route.paths.push(route.paths[0].clone());
+                               let mut payment_hash = PaymentHash([0; 32]);
+                               payment_hash.0[0..8].copy_from_slice(&be64_to_array(payments_sent));
+                               let mut sha = Sha256::engine();
+                               sha.input(&payment_hash.0[..]);
+                               payment_hash.0 = Sha256::from_engine(sha).into_inner();
+                               payments_sent += 1;
+                               let mut payment_secret = PaymentSecret([0; 32]);
+                               payment_secret.0[0..8].copy_from_slice(&be64_to_array(payments_sent));
+                               payments_sent += 1;
+                               match channelmanager.send_payment(&route, payment_hash, &Some(payment_secret)) {
                                        Ok(_) => {},
                                        Err(_) => return,
                                }
@@ -428,23 +449,23 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                }
                        },
                        8 => {
-                               for (payment, amt) in payments_received.drain(..) {
+                               for (payment, payment_secret, amt) in payments_received.drain(..) {
                                        // SHA256 is defined as XOR of all input bytes placed in the first byte, and 0s
                                        // for the remaining bytes. Thus, if not all remaining bytes are 0s we cannot
                                        // fulfill this HTLC, but if they are, we can just take the first byte and
                                        // place that anywhere in our preimage.
                                        if &payment.0[1..] != &[0; 31] {
-                                               channelmanager.fail_htlc_backwards(&payment);
+                                               channelmanager.fail_htlc_backwards(&payment, &payment_secret);
                                        } else {
                                                let mut payment_preimage = PaymentPreimage([0; 32]);
                                                payment_preimage.0[0] = payment.0[0];
-                                               channelmanager.claim_funds(payment_preimage, amt);
+                                               channelmanager.claim_funds(payment_preimage, &payment_secret, amt);
                                        }
                                }
                        },
                        9 => {
-                               for (payment, _) in payments_received.drain(..) {
-                                       channelmanager.fail_htlc_backwards(&payment);
+                               for (payment, payment_secret, _) in payments_received.drain(..) {
+                                       channelmanager.fail_htlc_backwards(&payment, &payment_secret);
                                }
                        },
                        10 => {
@@ -513,6 +534,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) });
                                channelmanager.force_close_channel(&channels[channel_id].channel_id);
                        },
+                       // 15 is above
                        _ => return,
                }
                loss_detector.handler.process_events();
@@ -524,9 +546,9 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                Event::FundingBroadcastSafe { funding_txo, .. } => {
                                        pending_funding_relay.push(pending_funding_signatures.remove(&funding_txo).unwrap());
                                },
-                               Event::PaymentReceived { payment_hash, amt } => {
+                               Event::PaymentReceived { payment_hash, payment_secret, amt } => {
                                        //TODO: enhance by fetching random amounts from fuzz input?
-                                       payments_received.push((payment_hash, amt));
+                                       payments_received.push((payment_hash, payment_secret, amt));
                                },
                                Event::PaymentSent {..} => {},
                                Event::PaymentFailed {..} => {},
index d43608f376b3417c0bee9a78aeead958a1c521ad..71e4d376f7d47b30568b8240119714fdc6723286 100644 (file)
@@ -4,7 +4,7 @@
 //! here. See also the chanmon_fail_consistency fuzz test.
 
 use chain::transaction::OutPoint;
-use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash};
+use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSendFailure};
 use ln::channelmonitor::ChannelMonitorUpdateErr;
 use ln::features::InitFeatures;
 use ln::msgs;
@@ -30,7 +30,7 @@ fn test_simple_monitor_permanent_update_fail() {
        let (_, payment_hash_1) = get_payment_preimage_hash!(&nodes[0]);
 
        *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::PermanentFailure);
-       if let Err(APIError::ChannelUnavailable {..}) = nodes[0].node.send_payment(route, payment_hash_1) {} else { panic!(); }
+       unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &None), true, APIError::ChannelUnavailable {..}, {});
        check_added_monitors!(nodes[0], 2);
 
        let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
@@ -63,7 +63,8 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) {
        let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(&nodes[0]);
 
        *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
-       if let Err(APIError::MonitorUpdateFailed) = nodes[0].node.send_payment(route.clone(), payment_hash_1) {} else { panic!(); }
+
+       unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &None), false, APIError::MonitorUpdateFailed, {});
        check_added_monitors!(nodes[0], 1);
 
        assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
@@ -93,8 +94,9 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) {
        let events_3 = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events_3.len(), 1);
        match events_3[0] {
-               Event::PaymentReceived { ref payment_hash, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
                        assert_eq!(payment_hash_1, *payment_hash);
+                       assert_eq!(*payment_secret, None);
                        assert_eq!(amt, 1000000);
                },
                _ => panic!("Unexpected event"),
@@ -105,7 +107,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) {
        // Now set it to failed again...
        let (_, payment_hash_2) = get_payment_preimage_hash!(&nodes[0]);
        *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
-       if let Err(APIError::MonitorUpdateFailed) = nodes[0].node.send_payment(route, payment_hash_2) {} else { panic!(); }
+       unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &None), false, APIError::MonitorUpdateFailed, {});
        check_added_monitors!(nodes[0], 1);
 
        assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
@@ -168,7 +170,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
        let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
 
        *nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
-       if let Err(APIError::MonitorUpdateFailed) = nodes[0].node.send_payment(route.clone(), payment_hash_2) {} else { panic!(); }
+       unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &None), false, APIError::MonitorUpdateFailed, {});
        check_added_monitors!(nodes[0], 1);
 
        assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
@@ -177,7 +179,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
 
        // Claim the previous payment, which will result in a update_fulfill_htlc/CS from nodes[1]
        // but nodes[0] won't respond since it is frozen.
-       assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
+       assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
        check_added_monitors!(nodes[1], 1);
        let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(events_2.len(), 1);
@@ -446,8 +448,9 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
        let events_5 = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events_5.len(), 1);
        match events_5[0] {
-               Event::PaymentReceived { ref payment_hash, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
                        assert_eq!(payment_hash_2, *payment_hash);
+                       assert_eq!(*payment_secret, None);
                        assert_eq!(amt, 1000000);
                },
                _ => panic!("Unexpected event"),
@@ -494,7 +497,7 @@ fn test_monitor_update_fail_cs() {
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let send_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0));
@@ -555,8 +558,9 @@ fn test_monitor_update_fail_cs() {
        let events = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
        match events[0] {
-               Event::PaymentReceived { payment_hash, amt } => {
+               Event::PaymentReceived { payment_hash, payment_secret, amt } => {
                        assert_eq!(payment_hash, our_payment_hash);
+                       assert_eq!(payment_secret, None);
                        assert_eq!(amt, 1000000);
                },
                _ => panic!("Unexpected event"),
@@ -578,7 +582,7 @@ fn test_monitor_update_fail_no_rebroadcast() {
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_1, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let send_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0));
@@ -626,13 +630,13 @@ fn test_monitor_update_raa_while_paused() {
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_1, our_payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash_1).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash_1, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let send_event_1 = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0));
 
        let route = nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_2, our_payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
-       nodes[1].node.send_payment(route, our_payment_hash_2).unwrap();
+       nodes[1].node.send_payment(&route, our_payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[1], 1);
        let send_event_2 = SendEvent::from_event(nodes[1].node.get_and_clear_pending_msg_events().remove(0));
 
@@ -701,7 +705,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
        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));
+       assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1, &None));
        expect_pending_htlcs_forwardable!(nodes[2]);
        check_added_monitors!(nodes[2], 1);
 
@@ -720,7 +724,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
        // holding cell.
        let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
        let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
-       nodes[0].node.send_payment(route, payment_hash_2).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let mut send_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0));
@@ -745,7 +749,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
 
        let (_, payment_hash_3) = get_payment_preimage_hash!(nodes[0]);
        let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
-       nodes[0].node.send_payment(route, payment_hash_3).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_3, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(()); // We succeed in updating the monitor for the first channel
@@ -792,7 +796,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
                // Try to route another payment backwards from 2 to make sure 1 holds off on responding
                let (payment_preimage_4, payment_hash_4) = get_payment_preimage_hash!(nodes[0]);
                let route = nodes[2].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
-               nodes[2].node.send_payment(route, payment_hash_4).unwrap();
+               nodes[2].node.send_payment(&route, payment_hash_4, &None).unwrap();
                check_added_monitors!(nodes[2], 1);
 
                send_event = SendEvent::from_event(nodes[2].node.get_and_clear_pending_msg_events().remove(0));
@@ -957,7 +961,7 @@ fn test_monitor_update_fail_reestablish() {
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
 
-       assert!(nodes[2].node.claim_funds(our_payment_preimage, 1_000_000));
+       assert!(nodes[2].node.claim_funds(our_payment_preimage, &None, 1_000_000));
        check_added_monitors!(nodes[2], 1);
        let mut updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
        assert!(updates.update_add_htlcs.is_empty());
@@ -1043,9 +1047,9 @@ fn raa_no_response_awaiting_raa_state() {
        // immediately after a CS. By setting failing the monitor update failure from the CS (which
        // requires only an RAA response due to AwaitingRAA) we can deliver the RAA and require the CS
        // generation during RAA while in monitor-update-failed state.
-       nodes[0].node.send_payment(route.clone(), payment_hash_1).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
-       nodes[0].node.send_payment(route.clone(), payment_hash_2).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[0], 0);
 
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -1093,7 +1097,7 @@ fn raa_no_response_awaiting_raa_state() {
        // We send a third payment here, which is somewhat of a redundant test, but the
        // chanmon_fail_consistency test required it to actually find the bug (by seeing out-of-sync
        // commitment transaction states) whereas here we can explicitly check for it.
-       nodes[0].node.send_payment(route.clone(), payment_hash_3).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_3, &None).unwrap();
        check_added_monitors!(nodes[0], 0);
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
@@ -1156,7 +1160,7 @@ fn claim_while_disconnected_monitor_update_fail() {
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
-       assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
+       assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
        check_added_monitors!(nodes[1], 1);
 
        nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
@@ -1182,7 +1186,7 @@ fn claim_while_disconnected_monitor_update_fail() {
        // the monitor still failed
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, payment_hash_2).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let as_updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
@@ -1274,7 +1278,7 @@ fn monitor_failed_no_reestablish_response() {
        // on receipt).
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, payment_hash_1).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        *nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
@@ -1344,7 +1348,7 @@ fn first_message_on_recv_ordering() {
        // can deliver it and fail the monitor update.
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, payment_hash_1).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -1366,7 +1370,7 @@ fn first_message_on_recv_ordering() {
        // Route the second payment, generating an update_add_htlc/commitment_signed
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, payment_hash_2).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 1);
@@ -1437,12 +1441,12 @@ fn test_monitor_update_fail_claim() {
        let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
 
        *nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
-       assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
+       assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
        check_added_monitors!(nodes[1], 1);
 
        let route = nodes[2].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (_, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
-       nodes[2].node.send_payment(route, payment_hash_2).unwrap();
+       nodes[2].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[2], 1);
 
        // Successfully update the monitor on the 1<->2 channel, but the 0<->1 channel should still be
@@ -1455,7 +1459,7 @@ fn test_monitor_update_fail_claim() {
        nodes[1].node.handle_update_add_htlc(&nodes[2].node.get_our_node_id(), &payment_event.msgs[0]);
        let events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 0);
-       nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1);
+       nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Temporary failure claiming HTLC, treating as success: Failed to update ChannelMonitor".to_string(), 1);
        commitment_signed_dance!(nodes[1], nodes[2], payment_event.commitment_msg, false, true);
 
        let bs_fail_update = get_htlc_update_msgs!(nodes[1], nodes[2].node.get_our_node_id());
@@ -1512,7 +1516,7 @@ fn test_monitor_update_on_pending_forwards() {
        send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000, 5_000_000);
 
        let (_, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
-       assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1));
+       assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1, &None));
        expect_pending_htlcs_forwardable!(nodes[2]);
        check_added_monitors!(nodes[2], 1);
 
@@ -1523,7 +1527,7 @@ fn test_monitor_update_on_pending_forwards() {
 
        let route = nodes[2].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
-       nodes[2].node.send_payment(route, payment_hash_2).unwrap();
+       nodes[2].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[2], 1);
 
        let mut events = nodes[2].node.get_and_clear_pending_msg_events();
@@ -1582,7 +1586,7 @@ fn monitor_update_claim_fail_no_response() {
        // Now start forwarding a second payment, skipping the last RAA so B is in AwaitingRAA
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, payment_hash_2).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -1592,11 +1596,11 @@ fn monitor_update_claim_fail_no_response() {
        let as_raa = commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false, true, false, true);
 
        *nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
-       assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
+       assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
        check_added_monitors!(nodes[1], 1);
        let events = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), 0);
-       nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Failed to update ChannelMonitor".to_string(), 1);
+       nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Temporary failure claiming HTLC, treating as success: Failed to update ChannelMonitor".to_string(), 1);
 
        *nodes[1].chan_monitor.update_ret.lock().unwrap() = Ok(());
        let (outpoint, latest_update) = nodes[1].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone();
index a471ca3f3675fcab67677381164c7dc69dd8903a..f9ccc18a0c707b66773a7421e9115a3b329f57b9 100644 (file)
@@ -30,7 +30,7 @@ use chain::transaction::OutPoint;
 use ln::channel::{Channel, ChannelError};
 use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, ManyChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
 use ln::features::{InitFeatures, NodeFeatures};
-use ln::router::Route;
+use ln::router::{Route, RouteHop};
 use ln::msgs;
 use ln::onion_utils;
 use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
@@ -68,12 +68,22 @@ use std::ops::Deref;
 // Alternatively, we can fill an outbound HTLC with a HTLCSource::OutboundRoute indicating this is
 // our payment, which we can use to decode errors or inform the user that the payment was sent.
 
+#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
+enum PendingHTLCRouting {
+       Forward {
+               onion_packet: msgs::OnionPacket,
+               short_channel_id: u64, // This should be NonZero<u64> eventually when we bump MSRV
+       },
+       Receive {
+               payment_data: Option<msgs::FinalOnionHopData>,
+       },
+}
+
 #[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
 pub(super) struct PendingHTLCInfo {
-       onion_packet: Option<msgs::OnionPacket>,
+       routing: PendingHTLCRouting,
        incoming_shared_secret: [u8; 32],
        payment_hash: PaymentHash,
-       short_channel_id: u64,
        pub(super) amt_to_forward: u64,
        pub(super) outgoing_cltv_value: u32,
 }
@@ -111,12 +121,22 @@ pub(super) struct HTLCPreviousHopData {
        incoming_packet_shared_secret: [u8; 32],
 }
 
+struct ClaimableHTLC {
+       prev_hop: HTLCPreviousHopData,
+       value: u64,
+       /// Filled in when the HTLC was received with a payment_secret packet, which contains a
+       /// total_msat (which may differ from value if this is a Multi-Path Payment) and a
+       /// payment_secret which prevents path-probing attacks and can associate different HTLCs which
+       /// are part of the same payment.
+       payment_data: Option<msgs::FinalOnionHopData>,
+}
+
 /// Tracks the inbound corresponding to an outbound HTLC
 #[derive(Clone, PartialEq)]
 pub(super) enum HTLCSource {
        PreviousHopData(HTLCPreviousHopData),
        OutboundRoute {
-               route: Route,
+               path: Vec<RouteHop>,
                session_priv: SecretKey,
                /// Technically we can recalculate this from the route, but we cache it here to avoid
                /// doing a double-pass on route when we get a failure back
@@ -127,7 +147,7 @@ pub(super) enum HTLCSource {
 impl HTLCSource {
        pub fn dummy() -> Self {
                HTLCSource::OutboundRoute {
-                       route: Route { hops: Vec::new() },
+                       path: Vec::new(),
                        session_priv: SecretKey::from_slice(&[1; 32]).unwrap(),
                        first_hop_htlc_msat: 0,
                }
@@ -151,6 +171,9 @@ pub struct PaymentHash(pub [u8;32]);
 /// payment_preimage type, use to route payment between hop
 #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)]
 pub struct PaymentPreimage(pub [u8;32]);
+/// payment_secret type, use to authenticate sender to the receiver and tie MPP HTLCs together
+#[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)]
+pub struct PaymentSecret(pub [u8;32]);
 
 type ShutdownResult = (Option<OutPoint>, ChannelMonitorUpdate, Vec<(HTLCSource, PaymentHash)>);
 
@@ -268,12 +291,14 @@ pub(super) struct ChannelHolder<ChanSigner: ChannelKeys> {
        /// guarantees are made about the existence of a channel with the short id here, nor the short
        /// ids in the PendingHTLCInfo!
        pub(super) forward_htlcs: HashMap<u64, Vec<HTLCForwardInfo>>,
-       /// payment_hash -> Vec<(amount_received, htlc_source)> for tracking things that were to us and
-       /// can be failed/claimed by the user
+       /// (payment_hash, payment_secret) -> Vec<HTLCs> for tracking HTLCs that
+       /// were to us and can be failed/claimed by the user
        /// Note that while this is held in the same mutex as the channels themselves, no consistency
        /// guarantees are made about the channels given here actually existing anymore by the time you
        /// go to read them!
-       pub(super) claimable_htlcs: HashMap<PaymentHash, Vec<(u64, HTLCPreviousHopData)>>,
+       /// TODO: We need to time out HTLCs sitting here which are waiting on other AMP HTLCs to
+       /// arrive.
+       claimable_htlcs: HashMap<(PaymentHash, Option<PaymentSecret>), Vec<ClaimableHTLC>>,
        /// Messages to send to peers - pushed to in the same lock that they are generated in (except
        /// for broadcast messages, where ordering isn't as strict).
        pub(super) pending_msg_events: Vec<events::MessageSendEvent>,
@@ -421,15 +446,6 @@ const CHECK_CLTV_EXPIRY_SANITY: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_P
 #[allow(dead_code)]
 const CHECK_CLTV_EXPIRY_SANITY_2: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2*CLTV_CLAIM_BUFFER;
 
-macro_rules! secp_call {
-       ( $res: expr, $err: expr ) => {
-               match $res {
-                       Ok(key) => key,
-                       Err(_) => return Err($err),
-               }
-       };
-}
-
 /// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels
 pub struct ChannelDetails {
        /// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
@@ -466,6 +482,42 @@ pub struct ChannelDetails {
        pub is_live: bool,
 }
 
+/// If a payment fails to send, it can be in one of several states. This enum is returned as the
+/// Err() type describing which state the payment is in, see the description of individual enum
+/// states for more.
+#[derive(Debug)]
+pub enum PaymentSendFailure {
+       /// A parameter which was passed to send_payment was invalid, preventing us from attempting to
+       /// send the payment at all. No channel state has been changed or messages sent to peers, and
+       /// once you've changed the parameter at error, you can freely retry the payment in full.
+       ParameterError(APIError),
+       /// A parameter in a single path which was passed to send_payment was invalid, preventing us
+       /// from attempting to send the payment at all. No channel state has been changed or messages
+       /// sent to peers, and once you've changed the parameter at error, you can freely retry the
+       /// payment in full.
+       ///
+       /// The results here are ordered the same as the paths in the route object which was passed to
+       /// send_payment.
+       PathParameterError(Vec<Result<(), APIError>>),
+       /// All paths which were attempted failed to send, with no channel state change taking place.
+       /// You can freely retry the payment in full (though you probably want to do so over different
+       /// paths than the ones selected).
+       AllFailedRetrySafe(Vec<APIError>),
+       /// Some paths which were attempted failed to send, though possibly not all. At least some
+       /// paths have irrevocably committed to the HTLC and retrying the payment in full would result
+       /// in over-/re-payment.
+       ///
+       /// The results here are ordered the same as the paths in the route object which was passed to
+       /// send_payment, and any Errs which are not APIError::MonitorUpdateFailed can be safely
+       /// retried (though there is currently no API with which to do so).
+       ///
+       /// Any entries which contain Err(APIError::MonitorUpdateFailed) or Ok(()) MUST NOT be retried
+       /// as they will result in over-/re-payment. These HTLCs all either successfully sent (in the
+       /// case of Ok(())) or will send once channel_monitor_updated is called on the next-hop channel
+       /// with the latest update_id.
+       PartialFailure(Vec<Result<(), APIError>>),
+}
+
 macro_rules! handle_error {
        ($self: ident, $internal: expr, $their_node_id: expr) => {
                match $internal {
@@ -999,15 +1051,20 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                        return_err!("Upstream node set CLTV to the wrong value", 18, &byte_utils::be32_to_array(msg.cltv_expiry));
                                }
 
+                               let payment_data = match next_hop_data.format {
+                                       msgs::OnionHopDataFormat::Legacy { .. } => None,
+                                       msgs::OnionHopDataFormat::NonFinalNode { .. } => return_err!("Got non final data with an HMAC of 0", 0x4000 | 22, &[0;0]),
+                                       msgs::OnionHopDataFormat::FinalNode { payment_data } => payment_data,
+                               };
+
                                // Note that we could obviously respond immediately with an update_fulfill_htlc
                                // message, however that would leak that we are the recipient of this payment, so
                                // instead we stay symmetric with the forwarding case, only responding (after a
                                // delay) once they've send us a commitment_signed!
 
                                PendingHTLCStatus::Forward(PendingHTLCInfo {
-                                       onion_packet: None,
+                                       routing: PendingHTLCRouting::Receive { payment_data },
                                        payment_hash: msg.payment_hash.clone(),
-                                       short_channel_id: 0,
                                        incoming_shared_secret: shared_secret,
                                        amt_to_forward: next_hop_data.amt_to_forward,
                                        outgoing_cltv_value: next_hop_data.outgoing_cltv_value,
@@ -1051,15 +1108,17 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                let short_channel_id = match next_hop_data.format {
                                        msgs::OnionHopDataFormat::Legacy { short_channel_id } => short_channel_id,
                                        msgs::OnionHopDataFormat::NonFinalNode { short_channel_id } => short_channel_id,
-                                       msgs::OnionHopDataFormat::FinalNode => {
+                                       msgs::OnionHopDataFormat::FinalNode { .. } => {
                                                return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0;0]);
                                        },
                                };
 
                                PendingHTLCStatus::Forward(PendingHTLCInfo {
-                                       onion_packet: Some(outgoing_packet),
+                                       routing: PendingHTLCRouting::Forward {
+                                               onion_packet: outgoing_packet,
+                                               short_channel_id: short_channel_id,
+                                       },
                                        payment_hash: msg.payment_hash.clone(),
-                                       short_channel_id: short_channel_id,
                                        incoming_shared_secret: shared_secret,
                                        amt_to_forward: next_hop_data.amt_to_forward,
                                        outgoing_cltv_value: next_hop_data.outgoing_cltv_value,
@@ -1067,8 +1126,11 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                        };
 
                channel_state = Some(self.channel_state.lock().unwrap());
-               if let &PendingHTLCStatus::Forward(PendingHTLCInfo { ref onion_packet, ref short_channel_id, ref amt_to_forward, ref outgoing_cltv_value, .. }) = &pending_forward_info {
-                       if onion_packet.is_some() { // If short_channel_id is 0 here, we'll reject them in the body here
+               if let &PendingHTLCStatus::Forward(PendingHTLCInfo { ref routing, ref amt_to_forward, ref outgoing_cltv_value, .. }) = &pending_forward_info {
+                       // If short_channel_id is 0 here, we'll reject the HTLC as there cannot be a channel
+                       // with a short_channel_id of 0. This is important as various things later assume
+                       // short_channel_id is non-0 in any ::Forward.
+                       if let &PendingHTLCRouting::Forward { ref short_channel_id, .. } = routing {
                                let id_option = channel_state.as_ref().unwrap().short_to_id.get(&short_channel_id).cloned();
                                let forwarding_id = match id_option {
                                        None => { // unknown_next_peer
@@ -1172,98 +1234,169 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
        /// payment_preimage tracking (which you should already be doing as they represent "proof of
        /// payment") and prevent double-sends yourself.
        ///
-       /// May generate a SendHTLCs message event on success, which should be relayed.
+       /// May generate SendHTLCs message(s) event on success, which should be relayed.
        ///
-       /// Raises APIError::RoutError when invalid route or forward parameter
-       /// (cltv_delta, fee, node public key) is specified.
-       /// Raises APIError::ChannelUnavailable if the next-hop channel is not available for updates
-       /// (including due to previous monitor update failure or new permanent monitor update failure).
-       /// Raised APIError::MonitorUpdateFailed if a new monitor update failure prevented sending the
-       /// relevant updates.
+       /// Each path may have a different return value, and PaymentSendValue may return a Vec with
+       /// each entry matching the corresponding-index entry in the route paths, see
+       /// PaymentSendFailure for more info.
        ///
-       /// In case of APIError::RouteError/APIError::ChannelUnavailable, the payment send has failed
-       /// and you may wish to retry via a different route immediately.
-       /// In case of APIError::MonitorUpdateFailed, the commitment update has been irrevocably
-       /// committed on our end and we're just waiting for a monitor update to send it. Do NOT retry
-       /// the payment via a different route unless you intend to pay twice!
-       pub fn send_payment(&self, route: Route, payment_hash: PaymentHash) -> Result<(), APIError> {
-               if route.hops.len() < 1 || route.hops.len() > 20 {
-                       return Err(APIError::RouteError{err: "Route didn't go anywhere/had bogus size"});
-               }
+       /// In general, a path may raise:
+       ///  * APIError::RouteError when an invalid route or forwarding parameter (cltv_delta, fee,
+       ///    node public key) is specified.
+       ///  * APIError::ChannelUnavailable if the next-hop channel is not available for updates
+       ///    (including due to previous monitor update failure or new permanent monitor update
+       ///    failure).
+       ///  * APIError::MonitorUpdateFailed if a new monitor update failure prevented sending the
+       ///    relevant updates.
+       ///
+       /// Note that depending on the type of the PaymentSendFailure the HTLC may have been
+       /// irrevocably committed to on our end. In such a case, do NOT retry the payment with a
+       /// different route unless you intend to pay twice!
+       ///
+       /// payment_secret is unrelated to payment_hash (or PaymentPreimage) and exists to authenticate
+       /// the sender to the recipient and prevent payment-probing (deanonymization) attacks. For
+       /// newer nodes, it will be provided to you in the invoice. If you do not have one, the Route
+       /// must not contain multiple paths as multi-path payments require a recipient-provided
+       /// payment_secret.
+       /// If a payment_secret *is* provided, we assume that the invoice had the payment_secret feature
+       /// bit set (either as required or as available). If multiple paths are present in the Route,
+       /// we assume the invoice had the basic_mpp feature set.
+       pub fn send_payment(&self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>) -> Result<(), PaymentSendFailure> {
+               if route.paths.len() < 1 {
+                       return Err(PaymentSendFailure::ParameterError(APIError::RouteError{err: "There must be at least one path to send over"}));
+               }
+               if route.paths.len() > 10 {
+                       // This limit is completely arbitrary - there aren't any real fundamental path-count
+                       // limits. After we support retrying individual paths we should likely bump this, but
+                       // for now more than 10 paths likely carries too much one-path failure.
+                       return Err(PaymentSendFailure::ParameterError(APIError::RouteError{err: "Sending over more than 10 paths is not currently supported"}));
+               }
+               let mut total_value = 0;
                let our_node_id = self.get_our_node_id();
-               for (idx, hop) in route.hops.iter().enumerate() {
-                       if idx != route.hops.len() - 1 && hop.pubkey == our_node_id {
-                               return Err(APIError::RouteError{err: "Route went through us but wasn't a simple rebalance loop to us"});
+               let mut path_errs = Vec::with_capacity(route.paths.len());
+               'path_check: for path in route.paths.iter() {
+                       if path.len() < 1 || path.len() > 20 {
+                               path_errs.push(Err(APIError::RouteError{err: "Path didn't go anywhere/had bogus size"}));
+                               continue 'path_check;
+                       }
+                       for (idx, hop) in path.iter().enumerate() {
+                               if idx != path.len() - 1 && hop.pubkey == our_node_id {
+                                       path_errs.push(Err(APIError::RouteError{err: "Path went through us but wasn't a simple rebalance loop to us"}));
+                                       continue 'path_check;
+                               }
                        }
+                       total_value += path.last().unwrap().fee_msat;
+                       path_errs.push(Ok(()));
+               }
+               if path_errs.iter().any(|e| e.is_err()) {
+                       return Err(PaymentSendFailure::PathParameterError(path_errs));
                }
-
-               let (session_priv, prng_seed) = self.keys_manager.get_onion_rand();
 
                let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
+               let mut results = Vec::new();
+               'path_loop: for path in route.paths.iter() {
+                       macro_rules! check_res_push {
+                               ($res: expr) => { match $res {
+                                               Ok(r) => r,
+                                               Err(e) => {
+                                                       results.push(Err(e));
+                                                       continue 'path_loop;
+                                               },
+                                       }
+                               }
+                       }
 
-               let onion_keys = secp_call!(onion_utils::construct_onion_keys(&self.secp_ctx, &route, &session_priv),
-                               APIError::RouteError{err: "Pubkey along hop was maliciously selected"});
-               let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height)?;
-               if onion_utils::route_size_insane(&onion_payloads) {
-                       return Err(APIError::RouteError{err: "Route size too large considering onion data"});
-               }
-               let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, prng_seed, &payment_hash);
+                       log_trace!(self, "Attempting to send payment for path with next hop {}", path.first().unwrap().short_channel_id);
+                       let (session_priv, prng_seed) = self.keys_manager.get_onion_rand();
 
-               let _ = self.total_consistency_lock.read().unwrap();
+                       let onion_keys = check_res_push!(onion_utils::construct_onion_keys(&self.secp_ctx, &path, &session_priv)
+                               .map_err(|_| APIError::RouteError{err: "Pubkey along hop was maliciously selected"}));
+                       let (onion_payloads, htlc_msat, htlc_cltv) = check_res_push!(onion_utils::build_onion_payloads(&path, total_value, payment_secret, cur_height));
+                       if onion_utils::route_size_insane(&onion_payloads) {
+                               check_res_push!(Err(APIError::RouteError{err: "Route size too large considering onion data"}));
+                       }
+                       let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, prng_seed, &payment_hash);
 
-               let err: Result<(), _> = loop {
-                       let mut channel_lock = self.channel_state.lock().unwrap();
-                       let id = match channel_lock.short_to_id.get(&route.hops.first().unwrap().short_channel_id) {
-                               None => return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!"}),
-                               Some(id) => id.clone(),
-                       };
+                       let _ = self.total_consistency_lock.read().unwrap();
 
-                       let channel_state = &mut *channel_lock;
-                       if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(id) {
-                               match {
-                                       if chan.get().get_their_node_id() != route.hops.first().unwrap().pubkey {
-                                               return Err(APIError::RouteError{err: "Node ID mismatch on first hop!"});
-                                       }
-                                       if !chan.get().is_live() {
-                                               return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected/pending monitor update!"});
-                                       }
-                                       break_chan_entry!(self, chan.get_mut().send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute {
-                                               route: route.clone(),
-                                               session_priv: session_priv.clone(),
-                                               first_hop_htlc_msat: htlc_msat,
-                                       }, onion_packet), channel_state, chan)
-                               } {
-                                       Some((update_add, commitment_signed, monitor_update)) => {
-                                               if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
-                                                       maybe_break_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true);
-                                                       // Note that MonitorUpdateFailed here indicates (per function docs)
-                                                       // that we will resent the commitment update once we unfree monitor
-                                                       // updating, so we have to take special care that we don't return
-                                                       // something else in case we will resend later!
-                                                       return Err(APIError::MonitorUpdateFailed);
+                       let err: Result<(), _> = loop {
+                               let mut channel_lock = self.channel_state.lock().unwrap();
+                               let id = match channel_lock.short_to_id.get(&path.first().unwrap().short_channel_id) {
+                                       None => check_res_push!(Err(APIError::ChannelUnavailable{err: "No channel available with first hop!"})),
+                                       Some(id) => id.clone(),
+                               };
+
+                               let channel_state = &mut *channel_lock;
+                               if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(id) {
+                                       match {
+                                               if chan.get().get_their_node_id() != path.first().unwrap().pubkey {
+                                                       check_res_push!(Err(APIError::RouteError{err: "Node ID mismatch on first hop!"}));
                                                }
+                                               if !chan.get().is_live() {
+                                                       check_res_push!(Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected/pending monitor update!"}));
+                                               }
+                                               break_chan_entry!(self, chan.get_mut().send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute {
+                                                       path: path.clone(),
+                                                       session_priv: session_priv.clone(),
+                                                       first_hop_htlc_msat: htlc_msat,
+                                               }, onion_packet), channel_state, chan)
+                                       } {
+                                               Some((update_add, commitment_signed, monitor_update)) => {
+                                                       if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
+                                                               maybe_break_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true);
+                                                               // Note that MonitorUpdateFailed here indicates (per function docs)
+                                                               // that we will resend the commitment update once monitor updating
+                                                               // is restored. Therefore, we must return an error indicating that
+                                                               // it is unsafe to retry the payment wholesale, which we do in the
+                                                               // next check for MonitorUpdateFailed, below.
+                                                               check_res_push!(Err(APIError::MonitorUpdateFailed));
+                                                       }
 
-                                               channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
-                                                       node_id: route.hops.first().unwrap().pubkey,
-                                                       updates: msgs::CommitmentUpdate {
-                                                               update_add_htlcs: vec![update_add],
-                                                               update_fulfill_htlcs: Vec::new(),
-                                                               update_fail_htlcs: Vec::new(),
-                                                               update_fail_malformed_htlcs: Vec::new(),
-                                                               update_fee: None,
-                                                               commitment_signed,
-                                                       },
-                                               });
-                                       },
-                                       None => {},
-                               }
-                       } else { unreachable!(); }
-                       return Ok(());
-               };
+                                                       channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
+                                                               node_id: path.first().unwrap().pubkey,
+                                                               updates: msgs::CommitmentUpdate {
+                                                                       update_add_htlcs: vec![update_add],
+                                                                       update_fulfill_htlcs: Vec::new(),
+                                                                       update_fail_htlcs: Vec::new(),
+                                                                       update_fail_malformed_htlcs: Vec::new(),
+                                                                       update_fee: None,
+                                                                       commitment_signed,
+                                                               },
+                                                       });
+                                               },
+                                               None => {},
+                                       }
+                               } else { unreachable!(); }
+                               results.push(Ok(()));
+                               continue 'path_loop;
+                       };
 
-               match handle_error!(self, err, route.hops.first().unwrap().pubkey) {
-                       Ok(_) => unreachable!(),
-                       Err(e) => { Err(APIError::ChannelUnavailable { err: e.err }) }
+                       match handle_error!(self, err, path.first().unwrap().pubkey) {
+                               Ok(_) => unreachable!(),
+                               Err(e) => {
+                                       check_res_push!(Err(APIError::ChannelUnavailable { err: e.err }));
+                               },
+                       }
+               }
+               let mut has_ok = false;
+               let mut has_err = false;
+               for res in results.iter() {
+                       if res.is_ok() { has_ok = true; }
+                       if res.is_err() { has_err = true; }
+                       if let &Err(APIError::MonitorUpdateFailed) = res {
+                               // MonitorUpdateFailed is inherently unsafe to retry, so we call it a
+                               // PartialFailure.
+                               has_err = true;
+                               has_ok = true;
+                               break;
+                       }
+               }
+               if has_err && has_ok {
+                       Err(PaymentSendFailure::PartialFailure(results))
+               } else if has_err {
+                       Err(PaymentSendFailure::AllFailedRetrySafe(results.drain(..).map(|r| r.unwrap_err()).collect()))
+               } else {
+                       Ok(())
                }
        }
 
@@ -1432,7 +1565,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                                                                        htlc_id: prev_htlc_id,
                                                                                        incoming_packet_shared_secret: forward_info.incoming_shared_secret,
                                                                                });
-                                                                               failed_forwards.push((htlc_source, forward_info.payment_hash, 0x4000 | 10, None));
+                                                                               failed_forwards.push((htlc_source, forward_info.payment_hash,
+                                                                                       HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() }
+                                                                               ));
                                                                        },
                                                                        HTLCForwardInfo::FailHTLC { .. } => {
                                                                                // Channel went away before we could fail it. This implies
@@ -1450,22 +1585,27 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                                let mut fail_htlc_msgs = Vec::new();
                                                for forward_info in pending_forwards.drain(..) {
                                                        match forward_info {
-                                                               HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
-                                                                       log_trace!(self, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", log_bytes!(forward_info.payment_hash.0), prev_short_channel_id, short_chan_id);
+                                                               HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
+                                                                               routing: PendingHTLCRouting::Forward {
+                                                                                       onion_packet, ..
+                                                                               }, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value }, } => {
+                                                                       log_trace!(self, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", log_bytes!(payment_hash.0), prev_short_channel_id, short_chan_id);
                                                                        let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
                                                                                short_channel_id: prev_short_channel_id,
                                                                                htlc_id: prev_htlc_id,
-                                                                               incoming_packet_shared_secret: forward_info.incoming_shared_secret,
+                                                                               incoming_packet_shared_secret: incoming_shared_secret,
                                                                        });
-                                                                       match chan.get_mut().send_htlc(forward_info.amt_to_forward, forward_info.payment_hash, forward_info.outgoing_cltv_value, htlc_source.clone(), forward_info.onion_packet.unwrap()) {
+                                                                       match chan.get_mut().send_htlc(amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source.clone(), onion_packet) {
                                                                                Err(e) => {
                                                                                        if let ChannelError::Ignore(msg) = e {
-                                                                                               log_trace!(self, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(forward_info.payment_hash.0), msg);
+                                                                                               log_trace!(self, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(payment_hash.0), msg);
                                                                                        } else {
                                                                                                panic!("Stated return value requirements in send_htlc() were not met");
                                                                                        }
                                                                                        let chan_update = self.get_channel_update(chan.get()).unwrap();
-                                                                                       failed_forwards.push((htlc_source, forward_info.payment_hash, 0x1000 | 7, Some(chan_update)));
+                                                                                       failed_forwards.push((htlc_source, payment_hash,
+                                                                                               HTLCFailReason::Reason { failure_code: 0x1000 | 7, data: chan_update.encode_with_len() }
+                                                                                       ));
                                                                                        continue;
                                                                                },
                                                                                Ok(update_add) => {
@@ -1484,6 +1624,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                                                                }
                                                                        }
                                                                },
+                                                               HTLCForwardInfo::AddHTLC { .. } => {
+                                                                       panic!("short_channel_id != 0 should imply any pending_forward entries are of type Forward");
+                                                               },
                                                                HTLCForwardInfo::FailHTLC { htlc_id, err_packet } => {
                                                                        log_trace!(self, "Failing HTLC back to channel with short id {} after delay", short_chan_id);
                                                                        match chan.get_mut().get_update_fail_htlc(htlc_id, err_packet) {
@@ -1561,20 +1704,60 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                } else {
                                        for forward_info in pending_forwards.drain(..) {
                                                match forward_info {
-                                                       HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
-                                                               let prev_hop_data = HTLCPreviousHopData {
+                                                       HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
+                                                                       routing: PendingHTLCRouting::Receive { payment_data },
+                                                                       incoming_shared_secret, payment_hash, amt_to_forward, .. }, } => {
+                                                               let prev_hop = HTLCPreviousHopData {
                                                                        short_channel_id: prev_short_channel_id,
                                                                        htlc_id: prev_htlc_id,
-                                                                       incoming_packet_shared_secret: forward_info.incoming_shared_secret,
-                                                               };
-                                                               match channel_state.claimable_htlcs.entry(forward_info.payment_hash) {
-                                                                       hash_map::Entry::Occupied(mut entry) => entry.get_mut().push((forward_info.amt_to_forward, prev_hop_data)),
-                                                                       hash_map::Entry::Vacant(entry) => { entry.insert(vec![(forward_info.amt_to_forward, prev_hop_data)]); },
+                                                                       incoming_packet_shared_secret: incoming_shared_secret,
                                                                };
-                                                               new_events.push(events::Event::PaymentReceived {
-                                                                       payment_hash: forward_info.payment_hash,
-                                                                       amt: forward_info.amt_to_forward,
+
+                                                               let mut total_value = 0;
+                                                               let payment_secret_opt =
+                                                                       if let &Some(ref data) = &payment_data { Some(data.payment_secret.clone()) } else { None };
+                                                               let htlcs = channel_state.claimable_htlcs.entry((payment_hash, payment_secret_opt))
+                                                                       .or_insert(Vec::new());
+                                                               htlcs.push(ClaimableHTLC {
+                                                                       prev_hop,
+                                                                       value: amt_to_forward,
+                                                                       payment_data: payment_data.clone(),
                                                                });
+                                                               if let &Some(ref data) = &payment_data {
+                                                                       for htlc in htlcs.iter() {
+                                                                               total_value += htlc.value;
+                                                                               if htlc.payment_data.as_ref().unwrap().total_msat != data.total_msat {
+                                                                                       total_value = msgs::MAX_VALUE_MSAT;
+                                                                               }
+                                                                               if total_value >= msgs::MAX_VALUE_MSAT { break; }
+                                                                       }
+                                                                       if total_value >= msgs::MAX_VALUE_MSAT || total_value > data.total_msat  {
+                                                                               for htlc in htlcs.iter() {
+                                                                                       failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData {
+                                                                                                       short_channel_id: htlc.prev_hop.short_channel_id,
+                                                                                                       htlc_id: htlc.prev_hop.htlc_id,
+                                                                                                       incoming_packet_shared_secret: htlc.prev_hop.incoming_packet_shared_secret,
+                                                                                               }), payment_hash,
+                                                                                               HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: byte_utils::be64_to_array(htlc.value).to_vec() }
+                                                                                       ));
+                                                                               }
+                                                                       } else if total_value == data.total_msat {
+                                                                               new_events.push(events::Event::PaymentReceived {
+                                                                                       payment_hash: payment_hash,
+                                                                                       payment_secret: Some(data.payment_secret),
+                                                                                       amt: total_value,
+                                                                               });
+                                                                       }
+                                                               } else {
+                                                                       new_events.push(events::Event::PaymentReceived {
+                                                                               payment_hash: payment_hash,
+                                                                               payment_secret: None,
+                                                                               amt: amt_to_forward,
+                                                                       });
+                                                               }
+                                                       },
+                                                       HTLCForwardInfo::AddHTLC { .. } => {
+                                                               panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
                                                        },
                                                        HTLCForwardInfo::FailHTLC { .. } => {
                                                                panic!("Got pending fail of our own HTLC");
@@ -1585,11 +1768,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                        }
                }
 
-               for (htlc_source, payment_hash, failure_code, update) in failed_forwards.drain(..) {
-                       match update {
-                               None => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source, &payment_hash, HTLCFailReason::Reason { failure_code, data: Vec::new() }),
-                               Some(chan_update) => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source, &payment_hash, HTLCFailReason::Reason { failure_code, data: chan_update.encode_with_len() }),
-                       };
+               for (htlc_source, payment_hash, failure_reason) in failed_forwards.drain(..) {
+                       self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source, &payment_hash, failure_reason);
                }
 
                for (their_node_id, err) in handle_errors.drain(..) {
@@ -1631,17 +1811,17 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
        /// along the path (including in our own channel on which we received it).
        /// Returns false if no payment was found to fail backwards, true if the process of failing the
        /// HTLC backwards has been started.
-       pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash) -> bool {
+       pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash, payment_secret: &Option<PaymentSecret>) -> bool {
                let _ = self.total_consistency_lock.read().unwrap();
 
                let mut channel_state = Some(self.channel_state.lock().unwrap());
-               let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(payment_hash);
+               let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&(*payment_hash, *payment_secret));
                if let Some(mut sources) = removed_source {
-                       for (recvd_value, htlc_with_hash) in sources.drain(..) {
+                       for htlc 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: 0x4000 | 15, data: byte_utils::be64_to_array(recvd_value).to_vec() });
+                                               HTLCSource::PreviousHopData(htlc.prev_hop), payment_hash,
+                                               HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: byte_utils::be64_to_array(htlc.value).to_vec() });
                        }
                        true
                } else { false }
@@ -1659,7 +1839,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                //between the branches here. We should make this async and move it into the forward HTLCs
                //timer handling.
                match source {
-                       HTLCSource::OutboundRoute { ref route, .. } => {
+                       HTLCSource::OutboundRoute { ref path, .. } => {
                                log_trace!(self, "Failing outbound payment HTLC with payment_hash {}", log_bytes!(payment_hash.0));
                                mem::drop(channel_state_lock);
                                match &onion_error {
@@ -1701,7 +1881,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                                self.pending_events.lock().unwrap().push(
                                                        events::Event::PaymentFailed {
                                                                payment_hash: payment_hash.clone(),
-                                                               rejected_by_dest: route.hops.len() == 1,
+                                                               rejected_by_dest: path.len() == 1,
 #[cfg(test)]
                                                                error_code: Some(*failure_code),
                                                        }
@@ -1756,97 +1936,169 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
        /// privacy-breaking recipient-probing attacks which may reveal payment activity to
        /// motivated attackers.
        ///
+       /// Note that the privacy concerns in (b) are not relevant in payments with a payment_secret
+       /// set. Thus, for such payments we will claim any payments which do not under-pay.
+       ///
        /// May panic if called except in response to a PaymentReceived event.
-       pub fn claim_funds(&self, payment_preimage: PaymentPreimage, expected_amount: u64) -> bool {
+       pub fn claim_funds(&self, payment_preimage: PaymentPreimage, payment_secret: &Option<PaymentSecret>, expected_amount: u64) -> bool {
                let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
 
                let _ = self.total_consistency_lock.read().unwrap();
 
                let mut channel_state = Some(self.channel_state.lock().unwrap());
-               let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&payment_hash);
+               let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&(payment_hash, *payment_secret));
                if let Some(mut sources) = removed_source {
-                       for (received_amount, htlc_with_hash) in sources.drain(..) {
+                       assert!(!sources.is_empty());
+
+                       // If we are claiming an MPP payment, we have to take special care to ensure that each
+                       // channel exists before claiming all of the payments (inside one lock).
+                       // Note that channel existance is sufficient as we should always get a monitor update
+                       // which will take care of the real HTLC claim enforcement.
+                       //
+                       // If we find an HTLC which we would need to claim but for which we do not have a
+                       // channel, we will fail all parts of the MPP payment. While we could wait and see if
+                       // the sender retries the already-failed path(s), it should be a pretty rare case where
+                       // we got all the HTLCs and then a channel closed while we were waiting for the user to
+                       // provide the preimage, so worrying too much about the optimal handling isn't worth
+                       // it.
+
+                       let (is_mpp, mut valid_mpp) = if let &Some(ref data) = &sources[0].payment_data {
+                               assert!(payment_secret.is_some());
+                               (true, data.total_msat >= expected_amount)
+                       } else {
+                               assert!(payment_secret.is_none());
+                               (false, false)
+                       };
+
+                       for htlc in sources.iter() {
+                               if !is_mpp || !valid_mpp { break; }
+                               if let None = channel_state.as_ref().unwrap().short_to_id.get(&htlc.prev_hop.short_channel_id) {
+                                       valid_mpp = false;
+                               }
+                       }
+
+                       let mut errs = Vec::new();
+                       let mut claimed_any_htlcs = false;
+                       for htlc in sources.drain(..) {
                                if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
-                               if received_amount < expected_amount || received_amount > expected_amount * 2 {
-                                       let mut htlc_msat_data = byte_utils::be64_to_array(received_amount).to_vec();
+                               if (is_mpp && !valid_mpp) || (!is_mpp && (htlc.value < expected_amount || htlc.value > expected_amount * 2)) {
+                                       let mut htlc_msat_data = byte_utils::be64_to_array(htlc.value).to_vec();
                                        let mut height_data = byte_utils::be32_to_array(self.latest_block_height.load(Ordering::Acquire) as u32).to_vec();
                                        htlc_msat_data.append(&mut height_data);
                                        self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
-                                                                        HTLCSource::PreviousHopData(htlc_with_hash), &payment_hash,
+                                                                        HTLCSource::PreviousHopData(htlc.prev_hop), &payment_hash,
                                                                         HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_data });
                                } else {
-                                       self.claim_funds_internal(channel_state.take().unwrap(), HTLCSource::PreviousHopData(htlc_with_hash), payment_preimage);
+                                       match self.claim_funds_from_hop(channel_state.as_mut().unwrap(), htlc.prev_hop, payment_preimage) {
+                                               Err(Some(e)) => {
+                                                       if let msgs::ErrorAction::IgnoreError = e.1.err.action {
+                                                               // We got a temporary failure updating monitor, but will claim the
+                                                               // HTLC when the monitor updating is restored (or on chain).
+                                                               log_error!(self, "Temporary failure claiming HTLC, treating as success: {}", e.1.err.err);
+                                                               claimed_any_htlcs = true;
+                                                       } else { errs.push(e); }
+                                               },
+                                               Err(None) if is_mpp => unreachable!("We already checked for channel existence, we can't fail here!"),
+                                               Err(None) => {
+                                                       log_warn!(self, "Channel we expected to claim an HTLC from was closed.");
+                                               },
+                                               Ok(()) => claimed_any_htlcs = true,
+                                       }
                                }
                        }
-                       true
+
+                       // Now that we've done the entire above loop in one lock, we can handle any errors
+                       // which were generated.
+                       channel_state.take();
+
+                       for (their_node_id, err) in errs.drain(..) {
+                               let res: Result<(), _> = Err(err);
+                               let _ = handle_error!(self, res, their_node_id);
+                       }
+
+                       claimed_any_htlcs
                } else { false }
        }
-       fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard<ChannelHolder<ChanSigner>>, source: HTLCSource, payment_preimage: PaymentPreimage) {
-               let (their_node_id, err) = loop {
-                       match source {
-                               HTLCSource::OutboundRoute { .. } => {
-                                       mem::drop(channel_state_lock);
-                                       let mut pending_events = self.pending_events.lock().unwrap();
-                                       pending_events.push(events::Event::PaymentSent {
-                                               payment_preimage
-                                       });
-                               },
-                               HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, .. }) => {
-                                       //TODO: Delay the claimed_funds relaying just like we do outbound relay!
-                                       let channel_state = &mut *channel_state_lock;
 
-                                       let chan_id = match channel_state.short_to_id.get(&short_channel_id) {
-                                               Some(chan_id) => chan_id.clone(),
-                                               None => {
-                                                       // TODO: There is probably a channel manager somewhere that needs to
-                                                       // learn the preimage as the channel already hit the chain and that's
-                                                       // why it's missing.
-                                                       return
-                                               }
-                                       };
+       fn claim_funds_from_hop(&self, channel_state_lock: &mut MutexGuard<ChannelHolder<ChanSigner>>, prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage) -> Result<(), Option<(PublicKey, MsgHandleErrInternal)>> {
+               //TODO: Delay the claimed_funds relaying just like we do outbound relay!
+               let channel_state = &mut **channel_state_lock;
+               let chan_id = match channel_state.short_to_id.get(&prev_hop.short_channel_id) {
+                       Some(chan_id) => chan_id.clone(),
+                       None => {
+                               return Err(None)
+                       }
+               };
 
-                                       if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(chan_id) {
-                                               let was_frozen_for_monitor = chan.get().is_awaiting_monitor_update();
-                                               match chan.get_mut().get_update_fulfill_htlc_and_commit(htlc_id, payment_preimage) {
-                                                       Ok((msgs, monitor_option)) => {
-                                                               if let Some(monitor_update) = monitor_option {
-                                                                       if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
-                                                                               if was_frozen_for_monitor {
-                                                                                       assert!(msgs.is_none());
-                                                                               } else {
-                                                                                       break (chan.get().get_their_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, msgs.is_some()));
-                                                                               }
-                                                                       }
-                                                               }
-                                                               if let Some((msg, commitment_signed)) = msgs {
-                                                                       channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
-                                                                               node_id: chan.get().get_their_node_id(),
-                                                                               updates: msgs::CommitmentUpdate {
-                                                                                       update_add_htlcs: Vec::new(),
-                                                                                       update_fulfill_htlcs: vec![msg],
-                                                                                       update_fail_htlcs: Vec::new(),
-                                                                                       update_fail_malformed_htlcs: Vec::new(),
-                                                                                       update_fee: None,
-                                                                                       commitment_signed,
-                                                                               }
-                                                                       });
-                                                               }
-                                                       },
-                                                       Err(_e) => {
-                                                               // TODO: There is probably a channel manager somewhere that needs to
-                                                               // learn the preimage as the channel may be about to hit the chain.
-                                                               //TODO: Do something with e?
-                                                               return
-                                                       },
+               if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(chan_id) {
+                       let was_frozen_for_monitor = chan.get().is_awaiting_monitor_update();
+                       match chan.get_mut().get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage) {
+                               Ok((msgs, monitor_option)) => {
+                                       if let Some(monitor_update) = monitor_option {
+                                               if let Err(e) = self.monitor.update_monitor(chan.get().get_funding_txo().unwrap(), monitor_update) {
+                                                       if was_frozen_for_monitor {
+                                                               assert!(msgs.is_none());
+                                                       } else {
+                                                               return Err(Some((chan.get().get_their_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, msgs.is_some()).unwrap_err())));
+                                                       }
                                                }
-                                       } else { unreachable!(); }
+                                       }
+                                       if let Some((msg, commitment_signed)) = msgs {
+                                               channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
+                                                       node_id: chan.get().get_their_node_id(),
+                                                       updates: msgs::CommitmentUpdate {
+                                                               update_add_htlcs: Vec::new(),
+                                                               update_fulfill_htlcs: vec![msg],
+                                                               update_fail_htlcs: Vec::new(),
+                                                               update_fail_malformed_htlcs: Vec::new(),
+                                                               update_fee: None,
+                                                               commitment_signed,
+                                                       }
+                                               });
+                                       }
+                                       return Ok(())
+                               },
+                               Err(e) => {
+                                       // TODO: Do something with e?
+                                       // This should only occur if we are claiming an HTLC at the same time as the
+                                       // HTLC is being failed (eg because a block is being connected and this caused
+                                       // an HTLC to time out). This should, of course, only occur if the user is the
+                                       // one doing the claiming (as it being a part of a peer claim would imply we're
+                                       // about to lose funds) and only if the lock in claim_funds was dropped as a
+                                       // previous HTLC was failed (thus not for an MPP payment).
+                                       debug_assert!(false, "This shouldn't be reachable except in absurdly rare cases between monitor updates and HTLC timeouts: {:?}", e);
+                                       return Err(None)
                                },
                        }
-                       return;
-               };
+               } else { unreachable!(); }
+       }
 
-               mem::drop(channel_state_lock);
-               let _ = handle_error!(self, err, their_node_id);
+       fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard<ChannelHolder<ChanSigner>>, source: HTLCSource, payment_preimage: PaymentPreimage) {
+               match source {
+                       HTLCSource::OutboundRoute { .. } => {
+                               mem::drop(channel_state_lock);
+                               let mut pending_events = self.pending_events.lock().unwrap();
+                               pending_events.push(events::Event::PaymentSent {
+                                       payment_preimage
+                               });
+                       },
+                       HTLCSource::PreviousHopData(hop_data) => {
+                               if let Err((their_node_id, err)) = match self.claim_funds_from_hop(&mut channel_state_lock, hop_data, payment_preimage) {
+                                       Ok(()) => Ok(()),
+                                       Err(None) => {
+                                               // TODO: There is probably a channel monitor somewhere that needs to
+                                               // learn the preimage as the channel already hit the chain and that's
+                                               // why it's missing.
+                                               Ok(())
+                                       },
+                                       Err(Some(res)) => Err(res),
+                               } {
+                                       mem::drop(channel_state_lock);
+                                       let res: Result<(), _> = Err(err);
+                                       let _ = handle_error!(self, res, their_node_id);
+                               }
+                       },
+               }
        }
 
        /// Gets the node_id held by this ChannelManager
@@ -2388,7 +2640,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
                                        forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS))
                                }
                                for (forward_info, prev_htlc_id) in pending_forwards.drain(..) {
-                                       match channel_state.forward_htlcs.entry(forward_info.short_channel_id) {
+                                       match channel_state.forward_htlcs.entry(match forward_info.routing {
+                                                       PendingHTLCRouting::Forward { short_channel_id, .. } => short_channel_id,
+                                                       PendingHTLCRouting::Receive { .. } => 0,
+                                       }) {
                                                hash_map::Entry::Occupied(mut entry) => {
                                                        entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info });
                                                },
@@ -3066,10 +3321,19 @@ const MIN_SERIALIZATION_VERSION: u8 = 1;
 
 impl Writeable for PendingHTLCInfo {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
-               self.onion_packet.write(writer)?;
+               match &self.routing {
+                       &PendingHTLCRouting::Forward { ref onion_packet, ref short_channel_id } => {
+                               0u8.write(writer)?;
+                               onion_packet.write(writer)?;
+                               short_channel_id.write(writer)?;
+                       },
+                       &PendingHTLCRouting::Receive { ref payment_data } => {
+                               1u8.write(writer)?;
+                               payment_data.write(writer)?;
+                       },
+               }
                self.incoming_shared_secret.write(writer)?;
                self.payment_hash.write(writer)?;
-               self.short_channel_id.write(writer)?;
                self.amt_to_forward.write(writer)?;
                self.outgoing_cltv_value.write(writer)?;
                Ok(())
@@ -3079,10 +3343,18 @@ impl Writeable for PendingHTLCInfo {
 impl Readable for PendingHTLCInfo {
        fn read<R: ::std::io::Read>(reader: &mut R) -> Result<PendingHTLCInfo, DecodeError> {
                Ok(PendingHTLCInfo {
-                       onion_packet: Readable::read(reader)?,
+                       routing: match Readable::read(reader)? {
+                               0u8 => PendingHTLCRouting::Forward {
+                                       onion_packet: Readable::read(reader)?,
+                                       short_channel_id: Readable::read(reader)?,
+                               },
+                               1u8 => PendingHTLCRouting::Receive {
+                                       payment_data: Readable::read(reader)?,
+                               },
+                               _ => return Err(DecodeError::InvalidValue),
+                       },
                        incoming_shared_secret: Readable::read(reader)?,
                        payment_hash: Readable::read(reader)?,
-                       short_channel_id: Readable::read(reader)?,
                        amt_to_forward: Readable::read(reader)?,
                        outgoing_cltv_value: Readable::read(reader)?,
                })
@@ -3147,6 +3419,12 @@ impl_writeable!(HTLCPreviousHopData, 0, {
        incoming_packet_shared_secret
 });
 
+impl_writeable!(ClaimableHTLC, 0, {
+       prev_hop,
+       value,
+       payment_data
+});
+
 impl Writeable for HTLCSource {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
                match self {
@@ -3154,9 +3432,9 @@ impl Writeable for HTLCSource {
                                0u8.write(writer)?;
                                hop_data.write(writer)?;
                        },
-                       &HTLCSource::OutboundRoute { ref route, ref session_priv, ref first_hop_htlc_msat } => {
+                       &HTLCSource::OutboundRoute { ref path, ref session_priv, ref first_hop_htlc_msat } => {
                                1u8.write(writer)?;
-                               route.write(writer)?;
+                               path.write(writer)?;
                                session_priv.write(writer)?;
                                first_hop_htlc_msat.write(writer)?;
                        }
@@ -3170,7 +3448,7 @@ impl Readable for HTLCSource {
                match <u8 as Readable>::read(reader)? {
                        0 => Ok(HTLCSource::PreviousHopData(Readable::read(reader)?)),
                        1 => Ok(HTLCSource::OutboundRoute {
-                               route: Readable::read(reader)?,
+                               path: Readable::read(reader)?,
                                session_priv: Readable::read(reader)?,
                                first_hop_htlc_msat: Readable::read(reader)?,
                        }),
@@ -3288,9 +3566,8 @@ impl<ChanSigner: ChannelKeys + Writeable, M: Deref, T: Deref, K: Deref, F: Deref
                for (payment_hash, previous_hops) in channel_state.claimable_htlcs.iter() {
                        payment_hash.write(writer)?;
                        (previous_hops.len() as u64).write(writer)?;
-                       for &(recvd_amt, ref previous_hop) in previous_hops.iter() {
-                               recvd_amt.write(writer)?;
-                               previous_hop.write(writer)?;
+                       for htlc in previous_hops.iter() {
+                               htlc.write(writer)?;
                        }
                }
 
@@ -3467,7 +3744,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De
                        let previous_hops_len: u64 = Readable::read(reader)?;
                        let mut previous_hops = Vec::with_capacity(cmp::min(previous_hops_len as usize, 2));
                        for _ in 0..previous_hops_len {
-                               previous_hops.push((Readable::read(reader)?, Readable::read(reader)?));
+                               previous_hops.push(Readable::read(reader)?);
                        }
                        claimable_htlcs.insert(payment_hash, previous_hops);
                }
index 18ea7bffbb8a5840ec7441e6171572630ea9573e..9ab53b4ae82c808745fec6b9d6e71a4cc9502650 100644 (file)
@@ -33,6 +33,14 @@ mod sealed { // You should just use the type aliases instead.
        pub trait VariableLengthOnion: Context {}
        impl VariableLengthOnion for InitContext {}
        impl VariableLengthOnion for NodeContext {}
+
+       pub trait PaymentSecret: Context {}
+       impl PaymentSecret for InitContext {}
+       impl PaymentSecret for NodeContext {}
+
+       pub trait BasicMPP: Context {}
+       impl BasicMPP for InitContext {}
+       impl BasicMPP for NodeContext {}
 }
 
 /// Tracks the set of features which a node implements, templated by the context in which it
@@ -73,7 +81,7 @@ impl InitFeatures {
        /// Create a Features with the features we support
        pub fn supported() -> InitFeatures {
                InitFeatures {
-                       flags: vec![2 | 1 << 5, 1 << (9-8)],
+                       flags: vec![2 | 1 << 5, 1 << (9-8) | 1 << (15 - 8), 1 << (17 - 8*2)],
                        mark: PhantomData,
                }
        }
@@ -136,14 +144,14 @@ impl NodeFeatures {
        #[cfg(not(feature = "fuzztarget"))]
        pub(crate) fn supported() -> NodeFeatures {
                NodeFeatures {
-                       flags: vec![2 | 1 << 5, 1 << (9-8)],
+                       flags: vec![2 | 1 << 5, 1 << (9 - 8) | 1 << (15 - 8), 1 << (17 - 8*2)],
                        mark: PhantomData,
                }
        }
        #[cfg(feature = "fuzztarget")]
        pub fn supported() -> NodeFeatures {
                NodeFeatures {
-                       flags: vec![2 | 1 << 5, 1 << (9-8)],
+                       flags: vec![2 | 1 << 5, 1 << (9 - 8) | 1 << (15 - 8), 1 << (17 - 8*2)],
                        mark: PhantomData,
                }
        }
@@ -199,8 +207,10 @@ impl<T: sealed::Context> Features<T> {
                                // unknown, upfront_shutdown_script, unknown (actually initial_routing_sync, but it
                                // is only valid as an optional feature), and data_loss_protect:
                                0 => (byte & 0b01000100),
-                               // unknown, unknown, unknown, var_onion_optin:
-                               1 => (byte & 0b01010100),
+                               // payment_secret, unknown, unknown, var_onion_optin:
+                               1 => (byte & 0b00010100),
+                               // unknown, unknown, unknown, basic_mpp:
+                               2 => (byte & 0b01010100),
                                // fallback, all even bits set:
                                _ => (byte & 0b01010101),
                        }) != 0
@@ -213,8 +223,10 @@ impl<T: sealed::Context> Features<T> {
                                // unknown, upfront_shutdown_script, initial_routing_sync (is only valid as an
                                // optional feature), and data_loss_protect:
                                0 => (byte & 0b11000100),
-                               // unknown, unknown, unknown, var_onion_optin:
-                               1 => (byte & 0b11111100),
+                               // payment_secret, unknown, unknown, var_onion_optin:
+                               1 => (byte & 0b00111100),
+                               // unknown, unknown, unknown, basic_mpp:
+                               2 => (byte & 0b11111100),
                                _ => byte,
                        }) != 0
                })
@@ -228,16 +240,19 @@ impl<T: sealed::Context> Features<T> {
 
        #[cfg(test)]
        pub(crate) fn set_require_unknown_bits(&mut self) {
-               let newlen = cmp::max(2, self.flags.len());
+               let newlen = cmp::max(3, self.flags.len());
                self.flags.resize(newlen, 0u8);
-               self.flags[1] |= 0x40;
+               self.flags[2] |= 0x40;
        }
 
        #[cfg(test)]
        pub(crate) fn clear_require_unknown_bits(&mut self) {
-               let newlen = cmp::max(2, self.flags.len());
+               let newlen = cmp::max(3, self.flags.len());
                self.flags.resize(newlen, 0u8);
-               self.flags[1] &= !0x40;
+               self.flags[2] &= !0x40;
+               if self.flags.len() == 3 && self.flags[2] == 0 {
+                       self.flags.resize(2, 0u8);
+               }
                if self.flags.len() == 2 && self.flags[1] == 0 {
                        self.flags.resize(1, 0u8);
                }
@@ -279,6 +294,24 @@ impl<T: sealed::InitialRoutingSync> Features<T> {
        }
 }
 
+impl<T: sealed::PaymentSecret> Features<T> {
+       #[allow(dead_code)]
+       // Note that we never need to test this since what really matters is the invoice - iff the
+       // invoice provides a payment_secret, we assume that we can use it (ie that the recipient
+       // supports payment_secret).
+       pub(crate) fn payment_secret(&self) -> bool {
+               self.flags.len() > 1 && (self.flags[1] & (3 << (14-8))) != 0
+       }
+}
+
+impl<T: sealed::BasicMPP> Features<T> {
+       // We currently never test for this since we don't actually *generate* multipath routes.
+       #[allow(dead_code)]
+       pub(crate) fn basic_mpp(&self) -> bool {
+               self.flags.len() > 2 && (self.flags[2] & (3 << (16-8*2))) != 0
+       }
+}
+
 impl<T: sealed::Context> Writeable for Features<T> {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
                w.size_hint(self.flags.len() + 2);
index 2da764b300b8bc2425aa7ff252fbba3749cdb7e9..95358208e9de283f2b78837e74cd78875d773a8e 100644 (file)
@@ -4,7 +4,7 @@
 use chain::chaininterface;
 use chain::transaction::OutPoint;
 use chain::keysinterface::KeysInterface;
-use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash};
+use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
 use ln::channelmonitor::{ChannelMonitor, ManyChannelMonitor};
 use ln::router::{Route, Router, RouterReadArgs};
 use ln::features::InitFeatures;
@@ -273,6 +273,28 @@ macro_rules! get_local_commitment_txn {
        }
 }
 
+macro_rules! unwrap_send_err {
+       ($res: expr, $all_failed: expr, $type: pat, $check: expr) => {
+               match &$res {
+                       &Err(PaymentSendFailure::AllFailedRetrySafe(ref fails)) if $all_failed => {
+                               assert_eq!(fails.len(), 1);
+                               match fails[0] {
+                                       $type => { $check },
+                                       _ => panic!(),
+                               }
+                       },
+                       &Err(PaymentSendFailure::PartialFailure(ref fails)) if !$all_failed => {
+                               assert_eq!(fails.len(), 1);
+                               match fails[0] {
+                                       Err($type) => { $check },
+                                       _ => panic!(),
+                               }
+                       },
+                       _ => panic!(),
+               }
+       }
+}
+
 pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_chan_value: u64, expected_user_chan_id: u64) -> ([u8; 32], Transaction, OutPoint) {
        let chan_id = *node.network_chan_count.borrow();
 
@@ -717,8 +739,9 @@ macro_rules! expect_payment_received {
                let events = $node.node.get_and_clear_pending_events();
                assert_eq!(events.len(), 1);
                match events[0] {
-                       Event::PaymentReceived { ref payment_hash, amt } => {
+                       Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
                                assert_eq!($expected_payment_hash, *payment_hash);
+                               assert_eq!(None, *payment_secret);
                                assert_eq!($expected_recv_value, amt);
                        },
                        _ => panic!("Unexpected event"),
@@ -753,130 +776,155 @@ macro_rules! expect_payment_failed {
        }
 }
 
-pub fn send_along_route_with_hash<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash) {
-       let mut payment_event = {
-               origin_node.node.send_payment(route, our_payment_hash).unwrap();
-               check_added_monitors!(origin_node, 1);
-
-               let mut events = origin_node.node.get_and_clear_pending_msg_events();
-               assert_eq!(events.len(), 1);
-               SendEvent::from_event(events.remove(0))
-       };
-       let mut prev_node = origin_node;
-
-       for (idx, &node) in expected_route.iter().enumerate() {
-               assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
-
-               node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
-               check_added_monitors!(node, 0);
-               commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
-
-               expect_pending_htlcs_forwardable!(node);
-
-               if idx == expected_route.len() - 1 {
-                       let events_2 = node.node.get_and_clear_pending_events();
-                       assert_eq!(events_2.len(), 1);
-                       match events_2[0] {
-                               Event::PaymentReceived { ref payment_hash, amt } => {
-                                       assert_eq!(our_payment_hash, *payment_hash);
-                                       assert_eq!(amt, recv_value);
-                               },
-                               _ => panic!("Unexpected event"),
+pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>) {
+       origin_node.node.send_payment(&route, our_payment_hash, &our_payment_secret).unwrap();
+       check_added_monitors!(origin_node, expected_paths.len());
+
+       let mut events = origin_node.node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), expected_paths.len());
+       for (path_idx, (ev, expected_route)) in events.drain(..).zip(expected_paths.iter()).enumerate() {
+               let mut payment_event = SendEvent::from_event(ev);
+               let mut prev_node = origin_node;
+
+               for (idx, &node) in expected_route.iter().enumerate() {
+                       assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
+
+                       node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
+                       check_added_monitors!(node, 0);
+                       commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
+
+                       expect_pending_htlcs_forwardable!(node);
+
+                       if idx == expected_route.len() - 1 {
+                               let events_2 = node.node.get_and_clear_pending_events();
+                               // Once we've gotten through all the HTLCs, the last one should result in a
+                               // PaymentReceived (but each previous one should not!).
+                               if path_idx == expected_paths.len() - 1 {
+                                       assert_eq!(events_2.len(), 1);
+                                       match events_2[0] {
+                                               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
+                                                       assert_eq!(our_payment_hash, *payment_hash);
+                                                       assert_eq!(our_payment_secret, *payment_secret);
+                                                       assert_eq!(amt, recv_value);
+                                               },
+                                               _ => panic!("Unexpected event"),
+                                       }
+                               } else {
+                                       assert!(events_2.is_empty());
+                               }
+                       } else {
+                               let mut events_2 = node.node.get_and_clear_pending_msg_events();
+                               assert_eq!(events_2.len(), 1);
+                               check_added_monitors!(node, 1);
+                               payment_event = SendEvent::from_event(events_2.remove(0));
+                               assert_eq!(payment_event.msgs.len(), 1);
                        }
-               } else {
-                       let mut events_2 = node.node.get_and_clear_pending_msg_events();
-                       assert_eq!(events_2.len(), 1);
-                       check_added_monitors!(node, 1);
-                       payment_event = SendEvent::from_event(events_2.remove(0));
-                       assert_eq!(payment_event.msgs.len(), 1);
-               }
 
-               prev_node = node;
+                       prev_node = node;
+               }
        }
 }
 
+pub fn send_along_route_with_hash<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash) {
+       send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, None);
+}
+
 pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
        let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(origin_node);
        send_along_route_with_hash(origin_node, route, expected_route, recv_value, our_payment_hash);
        (our_payment_preimage, our_payment_hash)
 }
 
-pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_preimage: PaymentPreimage, expected_amount: u64) {
-       assert!(expected_route.last().unwrap().node.claim_funds(our_payment_preimage, expected_amount));
-       check_added_monitors!(expected_route.last().unwrap(), 1);
+pub fn claim_payment_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<PaymentSecret>, expected_amount: u64) {
+       for path in expected_paths.iter() {
+               assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id());
+       }
+       assert!(expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage, &our_payment_secret, expected_amount));
+       check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
 
-       let mut next_msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)> = None;
-       let mut expected_next_node = expected_route.last().unwrap().node.get_our_node_id();
-       macro_rules! get_next_msgs {
-               ($node: expr) => {
-                       {
-                               let events = $node.node.get_and_clear_pending_msg_events();
-                               assert_eq!(events.len(), 1);
-                               match events[0] {
-                                       MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
-                                               assert!(update_add_htlcs.is_empty());
-                                               assert_eq!(update_fulfill_htlcs.len(), 1);
-                                               assert!(update_fail_htlcs.is_empty());
-                                               assert!(update_fail_malformed_htlcs.is_empty());
-                                               assert!(update_fee.is_none());
-                                               expected_next_node = node_id.clone();
-                                               Some((update_fulfill_htlcs[0].clone(), commitment_signed.clone()))
-                                       },
-                                       _ => panic!("Unexpected event"),
-                               }
+       macro_rules! msgs_from_ev {
+               ($ev: expr) => {
+                       match $ev {
+                               &MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
+                                       assert!(update_add_htlcs.is_empty());
+                                       assert_eq!(update_fulfill_htlcs.len(), 1);
+                                       assert!(update_fail_htlcs.is_empty());
+                                       assert!(update_fail_malformed_htlcs.is_empty());
+                                       assert!(update_fee.is_none());
+                                       ((update_fulfill_htlcs[0].clone(), commitment_signed.clone()), node_id.clone())
+                               },
+                               _ => panic!("Unexpected event"),
                        }
                }
        }
+       let mut per_path_msgs: Vec<((msgs::UpdateFulfillHTLC, msgs::CommitmentSigned), PublicKey)> = Vec::with_capacity(expected_paths.len());
+       let events = expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), expected_paths.len());
+       for ev in events.iter() {
+               per_path_msgs.push(msgs_from_ev!(ev));
+       }
 
-       macro_rules! last_update_fulfill_dance {
-               ($node: expr, $prev_node: expr) => {
-                       {
-                               $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
-                               check_added_monitors!($node, 0);
-                               assert!($node.node.get_and_clear_pending_msg_events().is_empty());
-                               commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
+       for (expected_route, (path_msgs, next_hop)) in expected_paths.iter().zip(per_path_msgs.drain(..)) {
+               let mut next_msgs = Some(path_msgs);
+               let mut expected_next_node = next_hop;
+
+               macro_rules! last_update_fulfill_dance {
+                       ($node: expr, $prev_node: expr) => {
+                               {
+                                       $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
+                                       check_added_monitors!($node, 0);
+                                       assert!($node.node.get_and_clear_pending_msg_events().is_empty());
+                                       commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
+                               }
                        }
                }
-       }
-       macro_rules! mid_update_fulfill_dance {
-               ($node: expr, $prev_node: expr, $new_msgs: expr) => {
-                       {
-                               $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
-                               check_added_monitors!($node, 1);
-                               let new_next_msgs = if $new_msgs {
-                                       get_next_msgs!($node)
-                               } else {
-                                       assert!($node.node.get_and_clear_pending_msg_events().is_empty());
-                                       None
-                               };
-                               commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
-                               next_msgs = new_next_msgs;
+               macro_rules! mid_update_fulfill_dance {
+                       ($node: expr, $prev_node: expr, $new_msgs: expr) => {
+                               {
+                                       $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
+                                       check_added_monitors!($node, 1);
+                                       let new_next_msgs = if $new_msgs {
+                                               let events = $node.node.get_and_clear_pending_msg_events();
+                                               assert_eq!(events.len(), 1);
+                                               let (res, nexthop) = msgs_from_ev!(&events[0]);
+                                               expected_next_node = nexthop;
+                                               Some(res)
+                                       } else {
+                                               assert!($node.node.get_and_clear_pending_msg_events().is_empty());
+                                               None
+                                       };
+                                       commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false);
+                                       next_msgs = new_next_msgs;
+                               }
                        }
                }
-       }
 
-       let mut prev_node = expected_route.last().unwrap();
-       for (idx, node) in expected_route.iter().rev().enumerate() {
-               assert_eq!(expected_next_node, node.node.get_our_node_id());
-               let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
-               if next_msgs.is_some() {
-                       mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
-               } else if update_next_msgs {
-                       next_msgs = get_next_msgs!(node);
-               } else {
-                       assert!(node.node.get_and_clear_pending_msg_events().is_empty());
-               }
-               if !skip_last && idx == expected_route.len() - 1 {
-                       assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
+               let mut prev_node = expected_route.last().unwrap();
+               for (idx, node) in expected_route.iter().rev().enumerate().skip(1) {
+                       assert_eq!(expected_next_node, node.node.get_our_node_id());
+                       let update_next_msgs = !skip_last || idx != expected_route.len() - 1;
+                       if next_msgs.is_some() {
+                               mid_update_fulfill_dance!(node, prev_node, update_next_msgs);
+                       } else {
+                               assert!(!update_next_msgs);
+                               assert!(node.node.get_and_clear_pending_msg_events().is_empty());
+                       }
+                       if !skip_last && idx == expected_route.len() - 1 {
+                               assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
+                       }
+
+                       prev_node = node;
                }
 
-               prev_node = node;
+               if !skip_last {
+                       last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
+                       expect_payment_sent!(origin_node, our_payment_preimage);
+               }
        }
+}
 
-       if !skip_last {
-               last_update_fulfill_dance!(origin_node, expected_route.first().unwrap());
-               expect_payment_sent!(origin_node, our_payment_preimage);
-       }
+pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_preimage: PaymentPreimage, expected_amount: u64) {
+       claim_payment_along_route_with_secret(origin_node, &[expected_route], skip_last, our_payment_preimage, None, expected_amount);
 }
 
 pub fn claim_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], our_payment_preimage: PaymentPreimage, expected_amount: u64) {
@@ -887,8 +935,9 @@ pub const TEST_FINAL_CLTV: u32 = 32;
 
 pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
        let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), None, &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap();
-       assert_eq!(route.hops.len(), expected_route.len());
-       for (node, hop) in expected_route.iter().zip(route.hops.iter()) {
+       assert_eq!(route.paths.len(), 1);
+       assert_eq!(route.paths[0].len(), expected_route.len());
+       for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) {
                assert_eq!(hop.pubkey, node.node.get_our_node_id());
        }
 
@@ -897,18 +946,15 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
 
 pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64)  {
        let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), None, &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap();
-       assert_eq!(route.hops.len(), expected_route.len());
-       for (node, hop) in expected_route.iter().zip(route.hops.iter()) {
+       assert_eq!(route.paths.len(), 1);
+       assert_eq!(route.paths[0].len(), expected_route.len());
+       for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) {
                assert_eq!(hop.pubkey, node.node.get_our_node_id());
        }
 
        let (_, our_payment_hash) = get_payment_preimage_hash!(origin_node);
-
-       let err = origin_node.node.send_payment(route, our_payment_hash).err().unwrap();
-       match err {
-               APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight our peer will accept"),
-               _ => panic!("Unknown error variants"),
-       };
+       unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+               assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight our peer will accept"));
 }
 
 pub fn send_payment<'a, 'b, 'c>(origin: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64, expected_value: u64)  {
@@ -917,7 +963,7 @@ pub fn send_payment<'a, 'b, 'c>(origin: &Node<'a, 'b, 'c>, expected_route: &[&No
 }
 
 pub fn fail_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], skip_last: bool, our_payment_hash: PaymentHash)  {
-       assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash));
+       assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash, &None));
        expect_pending_htlcs_forwardable!(expected_route.last().unwrap());
        check_added_monitors!(expected_route.last().unwrap(), 1);
 
index e6b9939efd9f0557fd6bb04318c603b26afe18f2..8c0f05723bf521fa4904815fb80649f26a24284b 100644 (file)
@@ -6,7 +6,7 @@ use chain::transaction::OutPoint;
 use chain::keysinterface::{ChannelKeys, KeysInterface, SpendableOutputDescriptor};
 use chain::chaininterface::{ChainListener, ChainWatchInterfaceUtil, BlockNotifier};
 use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC};
-use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,HTLCForwardInfo,RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT};
+use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,HTLCForwardInfo,RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure, BREAKDOWN_TIMEOUT};
 use ln::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ManyChannelMonitor, ANTI_REORG_DELAY};
 use ln::channel::{Channel, ChannelError};
 use ln::{chan_utils, onion_utils};
@@ -155,7 +155,7 @@ fn test_async_inbound_update_fee() {
 
        // ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]...
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[1].node.send_payment(nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 40000, TEST_FINAL_CLTV).unwrap(), our_payment_hash).unwrap();
+       nodes[1].node.send_payment(&nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 40000, TEST_FINAL_CLTV).unwrap(), our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[1], 1);
 
        let payment_event = {
@@ -251,7 +251,7 @@ fn test_update_fee_unordered_raa() {
 
        // ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]...
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[1].node.send_payment(nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 40000, TEST_FINAL_CLTV).unwrap(), our_payment_hash).unwrap();
+       nodes[1].node.send_payment(&nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 40000, TEST_FINAL_CLTV).unwrap(), our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[1], 1);
 
        let payment_event = {
@@ -642,7 +642,7 @@ fn test_update_fee_with_fundee_update_add_htlc() {
        let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[1]);
 
        // nothing happens since node[1] is in AwaitingRemoteRevoke
-       nodes[1].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[1].node.send_payment(&route, our_payment_hash, &None).unwrap();
        {
                let mut added_monitors = nodes[0].chan_monitor.added_monitors.lock().unwrap();
                assert_eq!(added_monitors.len(), 0);
@@ -861,12 +861,10 @@ fn updates_shutdown_wait() {
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
 
        let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       if let Err(APIError::ChannelUnavailable {..}) = nodes[0].node.send_payment(route_1, payment_hash) {}
-       else { panic!("New sends should fail!") };
-       if let Err(APIError::ChannelUnavailable {..}) = nodes[1].node.send_payment(route_2, payment_hash) {}
-       else { panic!("New sends should fail!") };
+       unwrap_send_err!(nodes[0].node.send_payment(&route_1, payment_hash, &None), true, APIError::ChannelUnavailable {..}, {});
+       unwrap_send_err!(nodes[1].node.send_payment(&route_2, payment_hash, &None), true, APIError::ChannelUnavailable {..}, {});
 
-       assert!(nodes[2].node.claim_funds(our_payment_preimage, 100_000));
+       assert!(nodes[2].node.claim_funds(our_payment_preimage, &None, 100_000));
        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());
@@ -924,7 +922,7 @@ fn htlc_fail_async_shutdown() {
 
        let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        assert_eq!(updates.update_add_htlcs.len(), 1);
@@ -1045,7 +1043,7 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
 
-       assert!(nodes[2].node.claim_funds(our_payment_preimage, 100_000));
+       assert!(nodes[2].node.claim_funds(our_payment_preimage, &None, 100_000));
        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());
@@ -1226,7 +1224,7 @@ fn fake_network_test() {
        });
        hops[1].fee_msat = chan_4.1.contents.fee_base_msat as u64 + chan_4.1.contents.fee_proportional_millionths as u64 * hops[2].fee_msat as u64 / 1000000;
        hops[0].fee_msat = chan_3.0.contents.fee_base_msat as u64 + chan_3.0.contents.fee_proportional_millionths as u64 * hops[1].fee_msat as u64 / 1000000;
-       let payment_preimage_1 = send_along_route(&nodes[1], Route { hops }, &vec!(&nodes[2], &nodes[3], &nodes[1])[..], 1000000).0;
+       let payment_preimage_1 = send_along_route(&nodes[1], Route { paths: vec![hops] }, &vec!(&nodes[2], &nodes[3], &nodes[1])[..], 1000000).0;
 
        let mut hops = Vec::with_capacity(3);
        hops.push(RouteHop {
@@ -1255,7 +1253,7 @@ fn fake_network_test() {
        });
        hops[1].fee_msat = chan_2.1.contents.fee_base_msat as u64 + chan_2.1.contents.fee_proportional_millionths as u64 * hops[2].fee_msat as u64 / 1000000;
        hops[0].fee_msat = chan_3.1.contents.fee_base_msat as u64 + chan_3.1.contents.fee_proportional_millionths as u64 * hops[1].fee_msat as u64 / 1000000;
-       let payment_hash_2 = send_along_route(&nodes[1], Route { hops }, &vec!(&nodes[3], &nodes[2], &nodes[1])[..], 1000000).1;
+       let payment_hash_2 = send_along_route(&nodes[1], Route { paths: vec![hops] }, &vec!(&nodes[3], &nodes[2], &nodes[1])[..], 1000000).1;
 
        // Claim the rebalances...
        fail_payment(&nodes[1], &vec!(&nodes[3], &nodes[2], &nodes[1])[..], payment_hash_2);
@@ -1305,7 +1303,7 @@ fn holding_cell_htlc_counting() {
        for _ in 0..::ln::channel::OUR_MAX_HTLCS {
                let route = nodes[1].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 100000, TEST_FINAL_CLTV).unwrap();
                let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[0]);
-               nodes[1].node.send_payment(route, payment_hash).unwrap();
+               nodes[1].node.send_payment(&route, payment_hash, &None).unwrap();
                payments.push((payment_preimage, payment_hash));
        }
        check_added_monitors!(nodes[1], 1);
@@ -1320,16 +1318,15 @@ fn holding_cell_htlc_counting() {
        // another HTLC.
        let route = nodes[1].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 100000, TEST_FINAL_CLTV).unwrap();
        let (_, payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
-       if let APIError::ChannelUnavailable { err } = nodes[1].node.send_payment(route, payment_hash_1).unwrap_err() {
-               assert_eq!(err, "Cannot push more than their max accepted HTLCs");
-       } else { panic!("Unexpected event"); }
+       unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash_1, &None), true, APIError::ChannelUnavailable { err },
+               assert_eq!(err, "Cannot push more than their max accepted HTLCs"));
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
        nodes[1].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot push more than their max accepted HTLCs".to_string(), 1);
 
        // This should also be true if we try to forward a payment.
        let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 100000, TEST_FINAL_CLTV).unwrap();
        let (_, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, payment_hash_2).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -1470,7 +1467,7 @@ fn test_duplicate_htlc_different_direction_onchain() {
        send_along_route_with_hash(&nodes[1], route, &vec!(&nodes[0])[..], 800_000, payment_hash);
 
        // Provide preimage to node 0 by claiming payment
-       nodes[0].node.claim_funds(payment_preimage, 800_000);
+       nodes[0].node.claim_funds(payment_preimage, &None, 800_000);
        check_added_monitors!(nodes[0], 1);
 
        // Broadcast node 1 commitment txn
@@ -1562,12 +1559,9 @@ fn do_channel_reserve_test(test_recv: bool) {
        // attempt to send amt_msat > their_max_htlc_value_in_flight_msat
        {
                let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_0 + 1);
-               assert!(route.hops.iter().rev().skip(1).all(|h| h.fee_msat == feemsat));
-               let err = nodes[0].node.send_payment(route, our_payment_hash).err().unwrap();
-               match err {
-                       APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight our peer will accept"),
-                       _ => panic!("Unknown error variants"),
-               }
+               assert!(route.paths[0].iter().rev().skip(1).all(|h| h.fee_msat == feemsat));
+               unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+                       assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight our peer will accept"));
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
                nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send value that would put us over the max HTLC value in flight our peer will accept".to_string(), 1);
        }
@@ -1601,11 +1595,8 @@ fn do_channel_reserve_test(test_recv: bool) {
                let recv_value = stat01.value_to_self_msat - stat01.channel_reserve_msat - total_fee_msat;
                // attempt to get channel_reserve violation
                let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value + 1);
-               let err = nodes[0].node.send_payment(route.clone(), our_payment_hash).err().unwrap();
-               match err {
-                       APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over their reserve value"),
-                       _ => panic!("Unknown error variants"),
-               }
+               unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+                       assert_eq!(err, "Cannot send value that would put us over their reserve value"));
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
                nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send value that would put us over their reserve value".to_string(), 1);
        }
@@ -1616,7 +1607,7 @@ fn do_channel_reserve_test(test_recv: bool) {
 
        let (route_1, our_payment_hash_1, our_payment_preimage_1) = get_route_and_payment_hash!(recv_value_1);
        let payment_event_1 = {
-               nodes[0].node.send_payment(route_1, our_payment_hash_1).unwrap();
+               nodes[0].node.send_payment(&route_1, our_payment_hash_1, &None).unwrap();
                check_added_monitors!(nodes[0], 1);
 
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -1629,10 +1620,8 @@ fn do_channel_reserve_test(test_recv: bool) {
        let recv_value_2 = stat01.value_to_self_msat - amt_msat_1 - stat01.channel_reserve_msat - total_fee_msat;
        {
                let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_2 + 1);
-               match nodes[0].node.send_payment(route, our_payment_hash).err().unwrap() {
-                       APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over their reserve value"),
-                       _ => panic!("Unknown error variants"),
-               }
+               unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+                       assert_eq!(err, "Cannot send value that would put us over their reserve value"));
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
                nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send value that would put us over their reserve value".to_string(), 2);
        }
@@ -1651,8 +1640,8 @@ fn do_channel_reserve_test(test_recv: bool) {
                }).expect("RNG is bad!");
 
                let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
-               let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route, &session_priv).unwrap();
-               let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
+               let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], recv_value_2 + 1, &None, cur_height).unwrap();
                let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash);
                let msg = msgs::UpdateAddHTLC {
                        channel_id: chan_1.2,
@@ -1686,7 +1675,7 @@ fn do_channel_reserve_test(test_recv: bool) {
        // now see if they go through on both sides
        let (route_21, our_payment_hash_21, our_payment_preimage_21) = get_route_and_payment_hash!(recv_value_21);
        // but this will stuck in the holding cell
-       nodes[0].node.send_payment(route_21, our_payment_hash_21).unwrap();
+       nodes[0].node.send_payment(&route_21, our_payment_hash_21, &None).unwrap();
        check_added_monitors!(nodes[0], 0);
        let events = nodes[0].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 0);
@@ -1694,17 +1683,15 @@ fn do_channel_reserve_test(test_recv: bool) {
        // test with outbound holding cell amount > 0
        {
                let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_22+1);
-               match nodes[0].node.send_payment(route, our_payment_hash).err().unwrap() {
-                       APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over their reserve value"),
-                       _ => panic!("Unknown error variants"),
-               }
+               unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+                       assert_eq!(err, "Cannot send value that would put us over their reserve value"));
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
                nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send value that would put us over their reserve value".to_string(), 3);
        }
 
        let (route_22, our_payment_hash_22, our_payment_preimage_22) = get_route_and_payment_hash!(recv_value_22);
        // this will also stuck in the holding cell
-       nodes[0].node.send_payment(route_22, our_payment_hash_22).unwrap();
+       nodes[0].node.send_payment(&route_22, our_payment_hash_22, &None).unwrap();
        check_added_monitors!(nodes[0], 0);
        assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
@@ -1754,15 +1741,17 @@ fn do_channel_reserve_test(test_recv: bool) {
        let events = nodes[2].node.get_and_clear_pending_events();
        assert_eq!(events.len(), 2);
        match events[0] {
-               Event::PaymentReceived { ref payment_hash, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
                        assert_eq!(our_payment_hash_21, *payment_hash);
+                       assert_eq!(*payment_secret, None);
                        assert_eq!(recv_value_21, amt);
                },
                _ => panic!("Unexpected event"),
        }
        match events[1] {
-               Event::PaymentReceived { ref payment_hash, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
                        assert_eq!(our_payment_hash_22, *payment_hash);
+                       assert_eq!(None, *payment_secret);
                        assert_eq!(recv_value_22, amt);
                },
                _ => panic!("Unexpected event"),
@@ -1826,7 +1815,7 @@ fn channel_reserve_in_flight_removes() {
        let (payment_preimage_3, payment_hash_3) = get_payment_preimage_hash!(nodes[0]);
        let send_1 = {
                let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
-               nodes[0].node.send_payment(route, payment_hash_3).unwrap();
+               nodes[0].node.send_payment(&route, payment_hash_3, &None).unwrap();
                check_added_monitors!(nodes[0], 1);
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
@@ -1835,13 +1824,13 @@ fn channel_reserve_in_flight_removes() {
 
        // Now claim both of the first two HTLCs on B's end, putting B in AwaitingRAA and generating an
        // initial fulfill/CS.
-       assert!(nodes[1].node.claim_funds(payment_preimage_1, b_chan_values.channel_reserve_msat - b_chan_values.value_to_self_msat - 10000));
+       assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, b_chan_values.channel_reserve_msat - b_chan_values.value_to_self_msat - 10000));
        check_added_monitors!(nodes[1], 1);
        let bs_removes = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
 
        // This claim goes in B's holding cell, allowing us to have a pending B->A RAA which does not
        // remove the second HTLC when we send the HTLC back from B to A.
-       assert!(nodes[1].node.claim_funds(payment_preimage_2, 20000));
+       assert!(nodes[1].node.claim_funds(payment_preimage_2, &None, 20000));
        check_added_monitors!(nodes[1], 1);
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
 
@@ -1898,7 +1887,7 @@ fn channel_reserve_in_flight_removes() {
        let (payment_preimage_4, payment_hash_4) = get_payment_preimage_hash!(nodes[1]);
        let send_2 = {
                let route = nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &[], 10000, TEST_FINAL_CLTV).unwrap();
-               nodes[1].node.send_payment(route, payment_hash_4).unwrap();
+               nodes[1].node.send_payment(&route, payment_hash_4, &None).unwrap();
                check_added_monitors!(nodes[1], 1);
                let mut events = nodes[1].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
@@ -1992,7 +1981,7 @@ fn channel_monitor_network_test() {
        macro_rules! claim_funds {
                ($node: expr, $prev_node: expr, $preimage: expr, $amount: expr) => {
                        {
-                               assert!($node.node.claim_funds($preimage, $amount));
+                               assert!($node.node.claim_funds($preimage, &None, $amount));
                                check_added_monitors!($node, 1);
 
                                let events = $node.node.get_and_clear_pending_msg_events();
@@ -2437,8 +2426,8 @@ fn test_htlc_on_chain_success() {
        let commitment_tx = get_local_commitment_txn!(nodes[2], chan_2.2);
        assert_eq!(commitment_tx.len(), 1);
        check_spends!(commitment_tx[0], chan_2.3);
-       nodes[2].node.claim_funds(our_payment_preimage, 3_000_000);
-       nodes[2].node.claim_funds(our_payment_preimage_2, 3_000_000);
+       nodes[2].node.claim_funds(our_payment_preimage, &None, 3_000_000);
+       nodes[2].node.claim_funds(our_payment_preimage_2, &None, 3_000_000);
        check_added_monitors!(nodes[2], 2);
        let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
        assert!(updates.update_add_htlcs.is_empty());
@@ -2613,7 +2602,7 @@ fn test_htlc_on_chain_timeout() {
        // Broadcast legit commitment tx from C on B's chain
        let commitment_tx = get_local_commitment_txn!(nodes[2], chan_2.2);
        check_spends!(commitment_tx[0], chan_2.3);
-       nodes[2].node.fail_htlc_backwards(&payment_hash);
+       nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
        check_added_monitors!(nodes[2], 0);
        expect_pending_htlcs_forwardable!(nodes[2]);
        check_added_monitors!(nodes[2], 1);
@@ -2803,7 +2792,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
        let (_, second_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value);
        let (_, third_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value);
 
-       assert!(nodes[2].node.fail_htlc_backwards(&first_payment_hash));
+       assert!(nodes[2].node.fail_htlc_backwards(&first_payment_hash, &None));
        expect_pending_htlcs_forwardable!(nodes[2]);
        check_added_monitors!(nodes[2], 1);
        let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
@@ -2816,7 +2805,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
        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));
+       assert!(nodes[2].node.fail_htlc_backwards(&second_payment_hash, &None));
        expect_pending_htlcs_forwardable!(nodes[2]);
        check_added_monitors!(nodes[2], 1);
        let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
@@ -2833,7 +2822,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
        nodes[2].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &as_raa);
        check_added_monitors!(nodes[2], 1);
 
-       assert!(nodes[2].node.fail_htlc_backwards(&third_payment_hash));
+       assert!(nodes[2].node.fail_htlc_backwards(&third_payment_hash, &None));
        expect_pending_htlcs_forwardable!(nodes[2]);
        check_added_monitors!(nodes[2], 1);
        let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
@@ -2856,7 +2845,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
        // on nodes[2]'s RAA.
        let route = nodes[1].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (_, fourth_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[1].node.send_payment(route, fourth_payment_hash).unwrap();
+       nodes[1].node.send_payment(&route, fourth_payment_hash, &None).unwrap();
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
        assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
        check_added_monitors!(nodes[1], 0);
@@ -3000,7 +2989,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
        {
                let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
                let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV).unwrap();
-               nodes[0].node.send_payment(route, payment_hash).unwrap();
+               nodes[0].node.send_payment(&route, payment_hash, &None).unwrap();
                check_added_monitors!(nodes[0], 1);
 
                let payment_event = {
@@ -3016,7 +3005,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
        let (_, failed_payment_hash) = get_payment_preimage_hash!(nodes[0]);
        {
                let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV).unwrap();
-               nodes[0].node.send_payment(route, failed_payment_hash).unwrap();
+               nodes[0].node.send_payment(&route, failed_payment_hash, &None).unwrap();
                check_added_monitors!(nodes[0], 0);
 
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
@@ -3036,8 +3025,8 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
                };
 
                let current_height = nodes[1].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
-               let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(&route, current_height).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route, &session_priv).unwrap();
+               let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(&route.paths[0], 50_000, &None, current_height).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
                let onion_routing_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash);
 
                // Send a 0-msat update_add_htlc to fail the channel.
@@ -3101,7 +3090,7 @@ fn test_force_close_fail_back() {
        let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
 
        let mut payment_event = {
-               nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+               nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
                check_added_monitors!(nodes[0], 1);
 
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -3272,7 +3261,7 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8) {
        let (payment_preimage_1, payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
 
        let payment_event = {
-               nodes[0].node.send_payment(route.clone(), payment_hash_1).unwrap();
+               nodes[0].node.send_payment(&route, payment_hash_1, &None).unwrap();
                check_added_monitors!(nodes[0], 1);
 
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -3347,14 +3336,15 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8) {
        let events_2 = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events_2.len(), 1);
        match events_2[0] {
-               Event::PaymentReceived { ref payment_hash, amt } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt } => {
                        assert_eq!(payment_hash_1, *payment_hash);
+                       assert_eq!(*payment_secret, None);
                        assert_eq!(amt, 1000000);
                },
                _ => panic!("Unexpected event"),
        }
 
-       nodes[1].node.claim_funds(payment_preimage_1, 1_000_000);
+       nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000);
        check_added_monitors!(nodes[1], 1);
 
        let events_3 = nodes[1].node.get_and_clear_pending_msg_events();
@@ -3563,7 +3553,7 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
        let (payment_preimage_2, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
 
-       nodes[0].node.send_payment(route.clone(), payment_hash_2).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash_2, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
@@ -3573,7 +3563,7 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
                _ => panic!("Unexpected event"),
        }
 
-       assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
+       assert!(nodes[1].node.claim_funds(payment_preimage_1, &None, 1_000_000));
        check_added_monitors!(nodes[1], 1);
 
        let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
@@ -3676,8 +3666,9 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
        let events_5 = nodes[1].node.get_and_clear_pending_events();
        assert_eq!(events_5.len(), 1);
        match events_5[0] {
-               Event::PaymentReceived { ref payment_hash, amt: _ } => {
+               Event::PaymentReceived { ref payment_hash, ref payment_secret, amt: _ } => {
                        assert_eq!(payment_hash_2, *payment_hash);
+                       assert_eq!(*payment_secret, None);
                },
                _ => panic!("Unexpected event"),
        }
@@ -4241,7 +4232,7 @@ fn test_static_spendable_outputs_preimage_tx() {
 
        // Settle A's commitment tx on B's chain
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-       assert!(nodes[1].node.claim_funds(payment_preimage, 3_000_000));
+       assert!(nodes[1].node.claim_funds(payment_preimage, &None, 3_000_000));
        check_added_monitors!(nodes[1], 1);
        nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()] }, 1);
        check_added_monitors!(nodes[1], 1);
@@ -4500,7 +4491,7 @@ fn test_onchain_to_onchain_claim() {
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
        let commitment_tx = get_local_commitment_txn!(nodes[2], chan_2.2);
        check_spends!(commitment_tx[0], chan_2.3);
-       nodes[2].node.claim_funds(payment_preimage, 3_000_000);
+       nodes[2].node.claim_funds(payment_preimage, &None, 3_000_000);
        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());
@@ -4618,7 +4609,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
                htlc_timeout_tx = node_txn[1].clone();
        }
 
-       nodes[2].node.claim_funds(our_payment_preimage, 900_000);
+       nodes[2].node.claim_funds(our_payment_preimage, &None, 900_000);
        nodes[2].block_notifier.block_connected(&Block { header, txdata: vec![commitment_txn[0].clone()] }, 1);
        check_added_monitors!(nodes[2], 3);
        let events = nodes[2].node.get_and_clear_pending_msg_events();
@@ -4714,7 +4705,7 @@ fn test_dynamic_spendable_outputs_local_htlc_success_tx() {
        check_spends!(local_txn[0], chan_1.3);
 
        // Give B knowledge of preimage to be able to generate a local HTLC-Success Tx
-       nodes[1].node.claim_funds(payment_preimage, 9_000_000);
+       nodes[1].node.claim_funds(payment_preimage, &None, 9_000_000);
        check_added_monitors!(nodes[1], 1);
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
        nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![local_txn[0].clone()] }, 1);
@@ -4816,10 +4807,10 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno
 
        // Now fail back three of the over-dust-limit and three of the under-dust-limit payments in one go.
        // Fail 0th below-dust, 4th above-dust, 8th above-dust, 10th below-dust HTLCs
-       assert!(nodes[4].node.fail_htlc_backwards(&payment_hash_1));
-       assert!(nodes[4].node.fail_htlc_backwards(&payment_hash_3));
-       assert!(nodes[4].node.fail_htlc_backwards(&payment_hash_5));
-       assert!(nodes[4].node.fail_htlc_backwards(&payment_hash_6));
+       assert!(nodes[4].node.fail_htlc_backwards(&payment_hash_1, &None));
+       assert!(nodes[4].node.fail_htlc_backwards(&payment_hash_3, &None));
+       assert!(nodes[4].node.fail_htlc_backwards(&payment_hash_5, &None));
+       assert!(nodes[4].node.fail_htlc_backwards(&payment_hash_6, &None));
        check_added_monitors!(nodes[4], 0);
        expect_pending_htlcs_forwardable!(nodes[4]);
        check_added_monitors!(nodes[4], 1);
@@ -4832,8 +4823,8 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno
        commitment_signed_dance!(nodes[3], nodes[4], four_removes.commitment_signed, false);
 
        // Fail 3rd below-dust and 7th above-dust HTLCs
-       assert!(nodes[5].node.fail_htlc_backwards(&payment_hash_2));
-       assert!(nodes[5].node.fail_htlc_backwards(&payment_hash_4));
+       assert!(nodes[5].node.fail_htlc_backwards(&payment_hash_2, &None));
+       assert!(nodes[5].node.fail_htlc_backwards(&payment_hash_4, &None));
        check_added_monitors!(nodes[5], 0);
        expect_pending_htlcs_forwardable!(nodes[5]);
        check_added_monitors!(nodes[5], 1);
@@ -5088,7 +5079,7 @@ fn do_htlc_claim_local_commitment_only(use_dust: bool) {
 
        // Claim the payment, but don't deliver A's commitment_signed, resulting in the HTLC only being
        // present in B's local commitment transaction, but none of A's commitment transactions.
-       assert!(nodes[1].node.claim_funds(our_payment_preimage, if use_dust { 50_000 } else { 3_000_000 }));
+       assert!(nodes[1].node.claim_funds(our_payment_preimage, &None, if use_dust { 50_000 } else { 3_000_000 }));
        check_added_monitors!(nodes[1], 1);
 
        let bs_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
@@ -5127,7 +5118,7 @@ fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) {
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), if use_dust { 50000 } else { 3000000 }, TEST_FINAL_CLTV).unwrap();
        let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let _as_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
@@ -5160,7 +5151,7 @@ fn do_htlc_claim_previous_remote_commitment_only(use_dust: bool, check_revoke_no
        // actually revoked.
        let htlc_value = if use_dust { 50000 } else { 3000000 };
        let (_, our_payment_hash) = route_payment(&nodes[0], &[&nodes[1]], htlc_value);
-       assert!(nodes[1].node.fail_htlc_backwards(&our_payment_hash));
+       assert!(nodes[1].node.fail_htlc_backwards(&our_payment_hash, &None));
        expect_pending_htlcs_forwardable!(nodes[1]);
        check_added_monitors!(nodes[1], 1);
 
@@ -5275,7 +5266,7 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case:
        }
 
        // 0 ~~> 2 send payment
-       nodes[0].node.send_payment(route.clone(), payment_hash.clone()).unwrap();
+       nodes[0].node.send_payment(&route, payment_hash.clone(), &None).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)
@@ -5466,8 +5457,8 @@ fn test_onion_failure() {
        run_onion_failure_test("invalid_realm", 0, &nodes, &route, &payment_hash, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
-               let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
+               let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, cur_height).unwrap();
                let mut new_payloads = Vec::new();
                for payload in onion_payloads.drain(..) {
                        new_payloads.push(BogusOnionHopData::new(payload));
@@ -5482,8 +5473,8 @@ fn test_onion_failure() {
        run_onion_failure_test("invalid_realm", 3, &nodes, &route, &payment_hash, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
-               let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
+               let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, cur_height).unwrap();
                let mut new_payloads = Vec::new();
                for payload in onion_payloads.drain(..) {
                        new_payloads.push(BogusOnionHopData::new(payload));
@@ -5503,57 +5494,57 @@ fn test_onion_failure() {
        }, |msg| {
                // and tamper returning error message
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::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}));
+       }, ||{}, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][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 returning error message
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], NODE|2, &[0;0]);
        }, ||{
-               nodes[2].node.fail_htlc_backwards(&payment_hash);
-       }, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: false}));
+               nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
+       }, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][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(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::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}));
+       }, ||{}, true, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][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(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|2, &[0;0]);
        }, ||{
-               nodes[2].node.fail_htlc_backwards(&payment_hash);
-       }, false, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: true}));
+               nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
+       }, false, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][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(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|3, &[0;0]);
        }, ||{
-               nodes[2].node.fail_htlc_backwards(&payment_hash);
-       }, true, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[0].pubkey, is_permanent: true}));
+               nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
+       }, true, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][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(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|3, &[0;0]);
        }, ||{
-               nodes[2].node.fail_htlc_backwards(&payment_hash);
-       }, false, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: true}));
+               nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
+       }, false, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][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);
@@ -5568,7 +5559,7 @@ fn test_onion_failure() {
                msg.amount_msat -= 1;
        }, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::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()}));
 
@@ -5576,7 +5567,7 @@ fn test_onion_failure() {
                msg.amount_msat -= 1;
        }, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::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}));
@@ -5585,20 +5576,20 @@ fn test_onion_failure() {
                msg.amount_msat -= 1;
        }, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
-               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
                msg.reason = onion_utils::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;
+       bogus_route.paths[0][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}));
+         Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: bogus_route.paths[0][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;
+       let route_len = bogus_route.paths[0].len();
+       bogus_route.paths[0][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
@@ -5620,7 +5611,7 @@ fn test_onion_failure() {
        }, ||{}, 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);
+               nodes[2].node.fail_htlc_backwards(&payment_hash, &None);
        }, false, Some(PERM|15), None);
 
        run_onion_failure_test("final_expiry_too_soon", 1, &nodes, &route, &payment_hash, |msg| {
@@ -5666,9 +5657,9 @@ fn test_onion_failure() {
                let session_priv = SecretKey::from_slice(&[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 = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
-               let (onion_payloads, _, htlc_cltv) = onion_utils::build_onion_payloads(&route, height).unwrap();
+               route.paths[0][1].cltv_expiry_delta += CLTV_FAR_FAR_AWAY + route.paths[0][0].cltv_expiry_delta + 1;
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
+               let (onion_payloads, _, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 40000, &None, height).unwrap();
                let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash);
                msg.cltv_expiry = htlc_cltv;
                msg.onion_routing_packet = onion_packet;
@@ -5758,15 +5749,10 @@ fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() {
        let mut route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
 
-       route.hops[0].fee_msat = 100;
-
-       let err = nodes[0].node.send_payment(route, our_payment_hash);
+       route.paths[0][0].fee_msat = 100;
 
-       if let Err(APIError::ChannelUnavailable{err}) = err {
-               assert_eq!(err, "Cannot send less than their minimum HTLC value");
-       } else {
-               assert!(false);
-       }
+       unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+               assert_eq!(err, "Cannot send less than their minimum HTLC value"));
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send less than their minimum HTLC value".to_string(), 1);
 }
@@ -5782,15 +5768,10 @@ fn test_update_add_htlc_bolt2_sender_zero_value_msat() {
        let mut route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
 
-       route.hops[0].fee_msat = 0;
-
-       let err = nodes[0].node.send_payment(route, our_payment_hash);
+       route.paths[0][0].fee_msat = 0;
 
-       if let Err(APIError::ChannelUnavailable{err}) = err {
-               assert_eq!(err, "Cannot send 0-msat HTLC");
-       } else {
-               assert!(false);
-       }
+       unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+               assert_eq!(err, "Cannot send 0-msat HTLC"));
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send 0-msat HTLC".to_string(), 1);
 }
@@ -5806,7 +5787,7 @@ fn test_update_add_htlc_bolt2_receiver_zero_value_msat() {
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
 
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        updates.update_add_htlcs[0].amount_msat = 0;
@@ -5829,13 +5810,8 @@ fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() {
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000000, 500000001).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
 
-       let err = nodes[0].node.send_payment(route, our_payment_hash);
-
-       if let Err(APIError::RouteError{err}) = err {
-               assert_eq!(err, "Channel CLTV overflowed?!");
-       } else {
-               assert!(false);
-       }
+       unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::RouteError { err },
+               assert_eq!(err, "Channel CLTV overflowed?!"));
 }
 
 #[test]
@@ -5854,7 +5830,7 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment()
                let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
                let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
                let payment_event = {
-                       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+                       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
                        check_added_monitors!(nodes[0], 1);
 
                        let mut events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -5875,13 +5851,9 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment()
        }
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       let err = nodes[0].node.send_payment(route, our_payment_hash);
+       unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+               assert_eq!(err, "Cannot push more than their max accepted HTLCs"));
 
-       if let Err(APIError::ChannelUnavailable{err}) = err {
-               assert_eq!(err, "Cannot push more than their max accepted HTLCs");
-       } else {
-               assert!(false);
-       }
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot push more than their max accepted HTLCs".to_string(), 1);
 }
@@ -5901,13 +5873,9 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_value_in_flight() {
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], max_in_flight+1, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       let err = nodes[0].node.send_payment(route, our_payment_hash);
+       unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { err },
+               assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight our peer will accept"));
 
-       if let Err(APIError::ChannelUnavailable{err}) = err {
-               assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight our peer will accept");
-       } else {
-               assert!(false);
-       }
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        nodes[0].logger.assert_log("lightning::ln::channelmanager".to_string(), "Cannot send value that would put us over the max HTLC value in flight our peer will accept".to_string(), 1);
 
@@ -5931,7 +5899,7 @@ fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() {
        }
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], htlc_minimum_msat, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        updates.update_add_htlcs[0].amount_msat = htlc_minimum_msat-1;
@@ -5955,7 +5923,7 @@ fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() {
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 5000000-their_channel_reserve, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
 
@@ -5988,8 +5956,8 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() {
        }).expect("RNG is bad!");
 
        let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
-       let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::signing_only(), &route, &session_priv).unwrap();
-       let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height).unwrap();
+       let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::signing_only(), &route.paths[0], &session_priv).unwrap();
+       let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 3999999, &None, cur_height).unwrap();
        let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash);
 
        let mut msg = msgs::UpdateAddHTLC {
@@ -6024,7 +5992,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() {
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, InitFeatures::supported(), InitFeatures::supported());
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        updates.update_add_htlcs[0].amount_msat = get_channel_value_stat!(nodes[1], chan.2).their_max_htlc_value_in_flight_msat + 1;
@@ -6046,7 +6014,7 @@ fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() {
        create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::supported(), InitFeatures::supported());
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 3999999, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        updates.update_add_htlcs[0].cltv_expiry = 500000000;
@@ -6070,7 +6038,7 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() {
        create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported());
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
@@ -6116,7 +6084,7 @@ fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() {
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap();
        let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
@@ -6147,7 +6115,7 @@ fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() {
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
@@ -6178,7 +6146,7 @@ fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment()
 
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
        let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
@@ -6210,7 +6178,7 @@ fn test_update_fulfill_htlc_bolt2_incorrect_htlc_id() {
 
        let our_payment_preimage = route_payment(&nodes[0], &[&nodes[1]], 100000).0;
 
-       nodes[1].node.claim_funds(our_payment_preimage, 100_000);
+       nodes[1].node.claim_funds(our_payment_preimage, &None, 100_000);
        check_added_monitors!(nodes[1], 1);
 
        let events = nodes[1].node.get_and_clear_pending_msg_events();
@@ -6251,7 +6219,7 @@ fn test_update_fulfill_htlc_bolt2_wrong_preimage() {
 
        let our_payment_preimage = route_payment(&nodes[0], &[&nodes[1]], 100000).0;
 
-       nodes[1].node.claim_funds(our_payment_preimage, 100_000);
+       nodes[1].node.claim_funds(our_payment_preimage, &None, 100_000);
        check_added_monitors!(nodes[1], 1);
 
        let events = nodes[1].node.get_and_clear_pending_msg_events();
@@ -6291,7 +6259,7 @@ fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_messag
        create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, InitFeatures::supported(), InitFeatures::supported());
        let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap();
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-       nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+       nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
        check_added_monitors!(nodes[0], 1);
 
        let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
@@ -6342,7 +6310,7 @@ fn test_update_fulfill_htlc_bolt2_after_malformed_htlc_message_must_forward_upda
 
        //First hop
        let mut payment_event = {
-               nodes[0].node.send_payment(route, our_payment_hash).unwrap();
+               nodes[0].node.send_payment(&route, our_payment_hash, &None).unwrap();
                check_added_monitors!(nodes[0], 1);
                let mut events = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(events.len(), 1);
@@ -6425,7 +6393,7 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) {
        let as_prev_commitment_tx = get_local_commitment_txn!(nodes[0], chan.2);
 
        // Fail one HTLC to prune it in the will-be-latest-local commitment tx
-       assert!(nodes[1].node.fail_htlc_backwards(&payment_hash_2));
+       assert!(nodes[1].node.fail_htlc_backwards(&payment_hash_2, &None));
        check_added_monitors!(nodes[1], 0);
        expect_pending_htlcs_forwardable!(nodes[1]);
        check_added_monitors!(nodes[1], 1);
@@ -6948,7 +6916,7 @@ fn test_check_htlc_underpaying() {
 
        // Node 3 is expecting payment of 100_000 but receive 10_000,
        // fail htlc like we didn't know the preimage.
-       nodes[1].node.claim_funds(payment_preimage, 100_000);
+       nodes[1].node.claim_funds(payment_preimage, &None, 100_000);
        nodes[1].node.process_pending_htlc_forwards();
 
        let events = nodes[1].node.get_and_clear_pending_msg_events();
@@ -7287,7 +7255,7 @@ fn test_bump_penalty_txn_on_remote_commitment() {
        assert_eq!(remote_txn[0].input[0].previous_output.txid, chan.3.txid());
 
        // Claim a HTLC without revocation (provide B monitor with preimage)
-       nodes[1].node.claim_funds(payment_preimage, 3_000_000);
+       nodes[1].node.claim_funds(payment_preimage, &None, 3_000_000);
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
        nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![remote_txn[0].clone()] }, 1);
        check_added_monitors!(nodes[1], 2);
@@ -7400,8 +7368,8 @@ fn test_set_outpoints_partial_claiming() {
        // Connect blocks on node A to advance height towards TEST_FINAL_CLTV
        let prev_header_100 = connect_blocks(&nodes[1].block_notifier, 100, 0, false, Default::default());
        // Provide node A with both preimage
-       nodes[0].node.claim_funds(payment_preimage_1, 3_000_000);
-       nodes[0].node.claim_funds(payment_preimage_2, 3_000_000);
+       nodes[0].node.claim_funds(payment_preimage_1, &None, 3_000_000);
+       nodes[0].node.claim_funds(payment_preimage_2, &None, 3_000_000);
        check_added_monitors!(nodes[0], 2);
        nodes[0].node.get_and_clear_pending_events();
        nodes[0].node.get_and_clear_pending_msg_events();
@@ -7585,3 +7553,58 @@ fn test_override_0msat_htlc_minimum() {
        let res = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
        assert_eq!(res.htlc_minimum_msat, 1);
 }
+
+#[test]
+fn test_simple_payment_secret() {
+       // Simple test of sending a payment with a payment_secret present. This does not use any AMP
+       // features, however.
+       let chanmon_cfgs = create_chanmon_cfgs(3);
+       let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
+       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported());
+       create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::supported(), InitFeatures::supported());
+
+       let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
+       let payment_secret = PaymentSecret([0xdb; 32]);
+       let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
+       send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2]]], 100000, payment_hash, Some(payment_secret.clone()));
+       // Claiming with all the correct values but the wrong secret should result in nothing...
+       assert_eq!(nodes[2].node.claim_funds(payment_preimage, &None, 100_000), false);
+       assert_eq!(nodes[2].node.claim_funds(payment_preimage, &Some(PaymentSecret([42; 32])), 100_000), false);
+       // ...but with the right secret we should be able to claim all the way back
+       claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage, Some(payment_secret.clone()), 100_000);
+}
+
+#[test]
+fn test_simple_mpp() {
+       // Simple test of sending a multi-path payment.
+       let chanmon_cfgs = create_chanmon_cfgs(4);
+       let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
+       let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
+
+       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
+       let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
+       let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
+       let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id;
+
+       let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]);
+       let payment_secret = PaymentSecret([0xdb; 32]);
+       let mut route = nodes[0].router.get_route(&nodes[3].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
+       let path = route.paths[0].clone();
+       route.paths.push(path);
+       route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
+       route.paths[0][0].short_channel_id = chan_1_id;
+       route.paths[0][1].short_channel_id = chan_3_id;
+       route.paths[1][0].pubkey = nodes[2].node.get_our_node_id();
+       route.paths[1][0].short_channel_id = chan_2_id;
+       route.paths[1][1].short_channel_id = chan_4_id;
+       send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], 200_000, payment_hash, Some(payment_secret.clone()));
+       // Claiming with all the correct values but the wrong secret should result in nothing...
+       assert_eq!(nodes[3].node.claim_funds(payment_preimage, &None, 200_000), false);
+       assert_eq!(nodes[3].node.claim_funds(payment_preimage, &Some(PaymentSecret([42; 32])), 200_000), false);
+       // ...but with the right secret we should be able to claim all the way back
+       claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage, Some(payment_secret), 200_000);
+}
index 85f3026eafa7930d705b9d7cc1b1b8fed3517b39..9698798c22ee0ae79ec24e002ef47220e616e2c4 100644 (file)
@@ -31,7 +31,10 @@ use std::result::Result;
 use util::events;
 use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt};
 
-use ln::channelmanager::{PaymentPreimage, PaymentHash};
+use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret};
+
+/// 21 million * 10^8 * 1000
+pub(crate) const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000;
 
 /// An error in decoding a message or struct.
 #[derive(Debug)]
@@ -612,8 +615,17 @@ pub trait RoutingMessageHandler : Send + Sync {
 }
 
 mod fuzzy_internal_msgs {
+       use ln::channelmanager::PaymentSecret;
+
        // These types aren't intended to be pub, but are exposed for direct fuzzing (as we deserialize
        // them from untrusted input):
+       #[derive(Clone)]
+       pub(crate) struct FinalOnionHopData {
+               pub(crate) payment_secret: PaymentSecret,
+               /// The total value, in msat, of the payment as received by the ultimate recipient.
+               /// Message serialization may panic if this value is more than 21 million Bitcoin.
+               pub(crate) total_msat: u64,
+       }
 
        pub(crate) enum OnionHopDataFormat {
                Legacy { // aka Realm-0
@@ -622,11 +634,15 @@ mod fuzzy_internal_msgs {
                NonFinalNode {
                        short_channel_id: u64,
                },
-               FinalNode,
+               FinalNode {
+                       payment_data: Option<FinalOnionHopData>,
+               },
        }
 
        pub struct OnionHopData {
                pub(crate) format: OnionHopDataFormat,
+               /// The value, in msat, of the payment after this hop's fee is deducted.
+               /// Message serialization may panic if this value is more than 21 million Bitcoin.
                pub(crate) amt_to_forward: u64,
                pub(crate) outgoing_cltv_value: u32,
                // 12 bytes of 0-padding for Legacy format
@@ -965,9 +981,29 @@ impl_writeable!(UpdateAddHTLC, 32+8+8+32+4+1366, {
        onion_routing_packet
 });
 
+impl Writeable for FinalOnionHopData {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+               w.size_hint(32 + 8 - (self.total_msat.leading_zeros()/8) as usize);
+               self.payment_secret.0.write(w)?;
+               HighZeroBytesDroppedVarInt(self.total_msat).write(w)
+       }
+}
+
+impl Readable for FinalOnionHopData {
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let secret: [u8; 32] = Readable::read(r)?;
+               let amt: HighZeroBytesDroppedVarInt<u64> = Readable::read(r)?;
+               Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0 })
+       }
+}
+
 impl Writeable for OnionHopData {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
                w.size_hint(33);
+               // Note that this should never be reachable if Rust-Lightning generated the message, as we
+               // check values are sane long before we get here, though its possible in the future
+               // user-generated messages may hit this.
+               if self.amt_to_forward > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
                match self.format {
                        OnionHopDataFormat::Legacy { short_channel_id } => {
                                0u8.write(w)?;
@@ -983,7 +1019,15 @@ impl Writeable for OnionHopData {
                                        (6, short_channel_id)
                                });
                        },
-                       OnionHopDataFormat::FinalNode => {
+                       OnionHopDataFormat::FinalNode { payment_data: Some(ref final_data) } => {
+                               if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
+                               encode_varint_length_prefixed_tlv!(w, {
+                                       (2, HighZeroBytesDroppedVarInt(self.amt_to_forward)),
+                                       (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value)),
+                                       (8, final_data)
+                               });
+                       },
+                       OnionHopDataFormat::FinalNode { payment_data: None } => {
                                encode_varint_length_prefixed_tlv!(w, {
                                        (2, HighZeroBytesDroppedVarInt(self.amt_to_forward)),
                                        (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value))
@@ -1008,19 +1052,29 @@ impl Readable for OnionHopData {
                        let mut amt = HighZeroBytesDroppedVarInt(0u64);
                        let mut cltv_value = HighZeroBytesDroppedVarInt(0u32);
                        let mut short_id: Option<u64> = None;
+                       let mut payment_data: Option<FinalOnionHopData> = None;
                        decode_tlv!(&mut rd, {
                                (2, amt),
                                (4, cltv_value)
                        }, {
-                               (6, short_id)
+                               (6, short_id),
+                               (8, payment_data)
                        });
                        rd.eat_remaining().map_err(|_| DecodeError::ShortRead)?;
                        let format = if let Some(short_channel_id) = short_id {
+                               if payment_data.is_some() { return Err(DecodeError::InvalidValue); }
                                OnionHopDataFormat::NonFinalNode {
                                        short_channel_id,
                                }
                        } else {
-                               OnionHopDataFormat::FinalNode
+                               if let &Some(ref data) = &payment_data {
+                                       if data.total_msat > MAX_VALUE_MSAT {
+                                               return Err(DecodeError::InvalidValue);
+                                       }
+                               }
+                               OnionHopDataFormat::FinalNode {
+                                       payment_data
+                               }
                        };
                        (format, amt.0, cltv_value.0)
                } else {
@@ -1033,6 +1087,9 @@ impl Readable for OnionHopData {
                        (format, amt, cltv_value)
                };
 
+               if amt > MAX_VALUE_MSAT {
+                       return Err(DecodeError::InvalidValue);
+               }
                Ok(OnionHopData {
                        format,
                        amt_to_forward: amt,
@@ -1305,8 +1362,8 @@ impl_writeable_len_match!(NodeAnnouncement, {
 mod tests {
        use hex;
        use ln::msgs;
-       use ln::msgs::{ChannelFeatures, InitFeatures, NodeFeatures, OptionalField, OnionErrorPacket, OnionHopDataFormat};
-       use ln::channelmanager::{PaymentPreimage, PaymentHash};
+       use ln::msgs::{ChannelFeatures, FinalOnionHopData, InitFeatures, NodeFeatures, OptionalField, OnionErrorPacket, OnionHopDataFormat};
+       use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret};
        use util::ser::{Writeable, Readable};
 
        use bitcoin_hashes::sha256d::Hash as Sha256dHash;
@@ -1998,7 +2055,9 @@ mod tests {
        #[test]
        fn encoding_final_onion_hop_data() {
                let mut msg = msgs::OnionHopData {
-                       format: OnionHopDataFormat::FinalNode,
+                       format: OnionHopDataFormat::FinalNode {
+                               payment_data: None,
+                       },
                        amt_to_forward: 0x0badf00d01020304,
                        outgoing_cltv_value: 0xffffffff,
                };
@@ -2006,7 +2065,36 @@ mod tests {
                let target_value = hex::decode("1002080badf00d010203040404ffffffff").unwrap();
                assert_eq!(encoded_value, target_value);
                msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
-               if let OnionHopDataFormat::FinalNode = msg.format { } else { panic!(); }
+               if let OnionHopDataFormat::FinalNode { payment_data: None } = msg.format { } else { panic!(); }
+               assert_eq!(msg.amt_to_forward, 0x0badf00d01020304);
+               assert_eq!(msg.outgoing_cltv_value, 0xffffffff);
+       }
+
+       #[test]
+       fn encoding_final_onion_hop_data_with_secret() {
+               let expected_payment_secret = PaymentSecret([0x42u8; 32]);
+               let mut msg = msgs::OnionHopData {
+                       format: OnionHopDataFormat::FinalNode {
+                               payment_data: Some(FinalOnionHopData {
+                                       payment_secret: expected_payment_secret,
+                                       total_msat: 0x1badca1f
+                               }),
+                       },
+                       amt_to_forward: 0x0badf00d01020304,
+                       outgoing_cltv_value: 0xffffffff,
+               };
+               let encoded_value = msg.encode();
+               let target_value = hex::decode("3602080badf00d010203040404ffffffff082442424242424242424242424242424242424242424242424242424242424242421badca1f").unwrap();
+               assert_eq!(encoded_value, target_value);
+               msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
+               if let OnionHopDataFormat::FinalNode {
+                       payment_data: Some(FinalOnionHopData {
+                               payment_secret,
+                               total_msat: 0x1badca1f
+                       })
+               } = msg.format {
+                       assert_eq!(payment_secret, expected_payment_secret);
+               } else { panic!(); }
                assert_eq!(msg.amt_to_forward, 0x0badf00d01020304);
                assert_eq!(msg.outgoing_cltv_value, 0xffffffff);
        }
index c2835460e22b9646f9a659686280283c99f577bf..ff89782bed3863681ae4d51176db3ad3af56ffae 100644 (file)
@@ -1,6 +1,6 @@
-use ln::channelmanager::{PaymentHash, HTLCSource};
+use ln::channelmanager::{PaymentHash, PaymentSecret, HTLCSource};
 use ln::msgs;
-use ln::router::{Route,RouteHop};
+use ln::router::RouteHop;
 use util::byte_utils;
 use util::chacha20::ChaCha20;
 use util::errors::{self, APIError};
@@ -63,11 +63,11 @@ pub(super) fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
 
 // 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)> (secp_ctx: &Secp256k1<T>, route: &Route, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {
+pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(SharedSecret, [u8; 32], PublicKey, &RouteHop)> (secp_ctx: &Secp256k1<T>, path: &Vec<RouteHop>, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {
        let mut blinded_priv = session_priv.clone();
        let mut blinded_pub = PublicKey::from_secret_key(secp_ctx, &blinded_priv);
 
-       for hop in route.hops.iter() {
+       for hop in path.iter() {
                let shared_secret = SharedSecret::new(&hop.pubkey, &blinded_priv);
 
                let mut sha = Sha256::engine();
@@ -87,10 +87,10 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
 }
 
 // can only fail if an intermediary hop has an invalid public key or session_priv is invalid
-pub(super) fn construct_onion_keys<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, route: &Route, session_priv: &SecretKey) -> Result<Vec<OnionKeys>, secp256k1::Error> {
-       let mut res = Vec::with_capacity(route.hops.len());
+pub(super) fn construct_onion_keys<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, path: &Vec<RouteHop>, session_priv: &SecretKey) -> Result<Vec<OnionKeys>, secp256k1::Error> {
+       let mut res = Vec::with_capacity(path.len());
 
-       construct_onion_keys_callback(secp_ctx, route, session_priv, |shared_secret, _blinding_factor, ephemeral_pubkey, _| {
+       construct_onion_keys_callback(secp_ctx, path, session_priv, |shared_secret, _blinding_factor, ephemeral_pubkey, _| {
                let (rho, mu) = gen_rho_mu_from_shared_secret(&shared_secret[..]);
 
                res.push(OnionKeys {
@@ -108,13 +108,13 @@ pub(super) fn construct_onion_keys<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T
 }
 
 /// returns the hop data, as well as the first-hop value_msat and CLTV value we should send.
-pub(super) fn build_onion_payloads(route: &Route, starting_htlc_offset: u32) -> Result<(Vec<msgs::OnionHopData>, u64, u32), APIError> {
+pub(super) fn build_onion_payloads(path: &Vec<RouteHop>, total_msat: u64, payment_secret_option: &Option<PaymentSecret>, starting_htlc_offset: u32) -> Result<(Vec<msgs::OnionHopData>, u64, u32), APIError> {
        let mut cur_value_msat = 0u64;
        let mut cur_cltv = starting_htlc_offset;
        let mut last_short_channel_id = 0;
-       let mut res: Vec<msgs::OnionHopData> = Vec::with_capacity(route.hops.len());
+       let mut res: Vec<msgs::OnionHopData> = Vec::with_capacity(path.len());
 
-       for (idx, hop) in route.hops.iter().rev().enumerate() {
+       for (idx, hop) in path.iter().rev().enumerate() {
                // First hop gets special values so that it can check, on receipt, that everything is
                // exactly as it should be (and the next hop isn't trying to probe to find out if we're
                // the intended recipient).
@@ -123,7 +123,14 @@ pub(super) fn build_onion_payloads(route: &Route, starting_htlc_offset: u32) ->
                res.insert(0, msgs::OnionHopData {
                        format: if hop.node_features.supports_variable_length_onion() {
                                if idx == 0 {
-                                       msgs::OnionHopDataFormat::FinalNode
+                                       msgs::OnionHopDataFormat::FinalNode {
+                                               payment_data: if let &Some(ref payment_secret) = payment_secret_option {
+                                                       Some(msgs::FinalOnionHopData {
+                                                               payment_secret: payment_secret.clone(),
+                                                               total_msat,
+                                                       })
+                                               } else { None },
+                                       }
                                } else {
                                        msgs::OnionHopDataFormat::NonFinalNode {
                                                short_channel_id: last_short_channel_id,
@@ -311,7 +318,7 @@ 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.
 pub(super) fn process_onion_failure<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, logger: &Arc<Logger>, htlc_source: &HTLCSource, mut packet_decrypted: Vec<u8>) -> (Option<msgs::HTLCFailChannelUpdate>, bool, Option<u16>) {
-       if let &HTLCSource::OutboundRoute { ref route, ref session_priv, ref first_hop_htlc_msat } = htlc_source {
+       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;
@@ -319,7 +326,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing>(secp_ctx: &Secp256k1<
                let mut is_from_final_node = false;
 
                // Handle packed channel/node updates for passing back for the route handler
-               construct_onion_keys_callback(secp_ctx, route, session_priv, |shared_secret, _, _, route_hop| {
+               construct_onion_keys_callback(secp_ctx, path, session_priv, |shared_secret, _, _, route_hop| {
                        next_route_hop_ix += 1;
                        if res.is_some() { return; }
 
@@ -334,7 +341,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing>(secp_ctx: &Secp256k1<
                        chacha.process(&packet_decrypted, &mut decryption_tmp[..]);
                        packet_decrypted = decryption_tmp;
 
-                       is_from_final_node = route.hops.last().unwrap().pubkey == route_hop.pubkey;
+                       is_from_final_node = path.last().unwrap().pubkey == route_hop.pubkey;
 
                        if let Ok(err_packet) = msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet_decrypted)) {
                                let um = gen_um_from_shared_secret(&shared_secret[..]);
@@ -367,7 +374,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing>(secp_ctx: &Secp256k1<
                                                }
                                                else if error_code & PERM == PERM {
                                                        fail_channel_update = if payment_failed {None} else {Some(msgs::HTLCFailChannelUpdate::ChannelClosed {
-                                                               short_channel_id: route.hops[next_route_hop_ix - if next_route_hop_ix == route.hops.len() { 1 } else { 0 }].short_channel_id,
+                                                               short_channel_id: path[next_route_hop_ix - if next_route_hop_ix == path.len() { 1 } else { 0 }].short_channel_id,
                                                                is_permanent: true,
                                                        })};
                                                }
@@ -478,7 +485,7 @@ mod tests {
                let secp_ctx = Secp256k1::new();
 
                let route = Route {
-                       hops: vec!(
+                       paths: vec![vec![
                                        RouteHop {
                                                pubkey: PublicKey::from_slice(&hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]).unwrap(),
                                                channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
@@ -504,13 +511,13 @@ mod tests {
                                                channel_features: ChannelFeatures::empty(), node_features: NodeFeatures::empty(),
                                                short_channel_id: 0, fee_msat: 0, cltv_expiry_delta: 0 // Test vectors are garbage and not generateble from a RouteHop, we fill in payloads manually
                                        },
-                       ),
+                       ]],
                };
 
                let session_priv = SecretKey::from_slice(&hex::decode("4141414141414141414141414141414141414141414141414141414141414141").unwrap()[..]).unwrap();
 
-               let onion_keys = super::construct_onion_keys(&secp_ctx, &route, &session_priv).unwrap();
-               assert_eq!(onion_keys.len(), route.hops.len());
+               let onion_keys = super::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
+               assert_eq!(onion_keys.len(), route.paths[0].len());
                onion_keys
        }
 
index bfc0f56698103b7cb7d54f9b19f74dfe0355f27b..6b2c5d43234125ecd1ce07bc0292eb71407fbc62 100644 (file)
@@ -39,7 +39,7 @@ fn do_test_onchain_htlc_reorg(local_commitment: bool, claim: bool) {
        let (our_payment_preimage, our_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
 
        // Provide preimage to node 2 by claiming payment
-       nodes[2].node.claim_funds(our_payment_preimage, 1000000);
+       nodes[2].node.claim_funds(our_payment_preimage, &None, 1000000);
        check_added_monitors!(nodes[2], 1);
        get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
 
index 950072504e37b81d4021c6abf08050ced32638fc..c7ebe86d7eb0d9b607c68b3831a990e76e61468e 100644 (file)
@@ -47,19 +47,10 @@ pub struct RouteHop {
        pub cltv_expiry_delta: u32,
 }
 
-/// A route from us through the network to a destination
-#[derive(Clone, PartialEq)]
-pub struct Route {
-       /// The list of hops, NOT INCLUDING our own, where the last hop is the destination. Thus, this
-       /// must always be at least length one. By protocol rules, this may not currently exceed 20 in
-       /// length.
-       pub hops: Vec<RouteHop>,
-}
-
-impl Writeable for Route {
+impl Writeable for Vec<RouteHop> {
        fn write<W: ::util::ser::Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
-               (self.hops.len() as u8).write(writer)?;
-               for hop in self.hops.iter() {
+               (self.len() as u8).write(writer)?;
+               for hop in self.iter() {
                        hop.pubkey.write(writer)?;
                        hop.node_features.write(writer)?;
                        hop.short_channel_id.write(writer)?;
@@ -71,8 +62,8 @@ impl Writeable for Route {
        }
 }
 
-impl Readable for Route {
-       fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Route, DecodeError> {
+impl Readable for Vec<RouteHop> {
+       fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Vec<RouteHop>, DecodeError> {
                let hops_count: u8 = Readable::read(reader)?;
                let mut hops = Vec::with_capacity(hops_count as usize);
                for _ in 0..hops_count {
@@ -85,9 +76,41 @@ impl Readable for Route {
                                cltv_expiry_delta: Readable::read(reader)?,
                        });
                }
-               Ok(Route {
-                       hops
-               })
+               Ok(hops)
+       }
+}
+
+/// A route directs a payment from the sender (us) to the recipient. If the recipient supports MPP,
+/// it can take multiple paths. Each path is composed of one or more hops through the network.
+#[derive(Clone, PartialEq)]
+pub struct Route {
+       /// The list of routes taken for a single (potentially-)multi-part payment. The pubkey of the
+       /// last RouteHop in each path must be the same.
+       /// Each entry represents a list of hops, NOT INCLUDING our own, where the last hop is the
+       /// destination. Thus, this must always be at least length one. While the maximum length of any
+       /// given path is variable, keeping the length of any path to less than 20 should currently
+       /// ensure it is viable.
+       pub paths: Vec<Vec<RouteHop>>,
+}
+
+impl Writeable for Route {
+       fn write<W: ::util::ser::Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+               (self.paths.len() as u64).write(writer)?;
+               for hops in self.paths.iter() {
+                       hops.write(writer)?;
+               }
+               Ok(())
+       }
+}
+
+impl Readable for Route {
+       fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Route, DecodeError> {
+               let path_count: u64 = Readable::read(reader)?;
+               let mut paths = Vec::with_capacity(cmp::min(path_count, 128) as usize);
+               for _ in 0..path_count {
+                       paths.push(Readable::read(reader)?);
+               }
+               Ok(Route { paths })
        }
 }
 
@@ -868,14 +891,14 @@ impl Router {
                                let short_channel_id = chan.short_channel_id.expect("first_hops should be filled in with usable channels, not pending ones");
                                if chan.remote_network_id == *target {
                                        return Ok(Route {
-                                               hops: vec![RouteHop {
+                                               paths: vec![vec![RouteHop {
                                                        pubkey: chan.remote_network_id,
                                                        node_features: NodeFeatures::with_known_relevant_init_flags(&chan.counterparty_features),
                                                        short_channel_id,
                                                        channel_features: ChannelFeatures::with_known_relevant_init_flags(&chan.counterparty_features),
                                                        fee_msat: final_value_msat,
                                                        cltv_expiry_delta: final_cltv,
-                                               }],
+                                               }]],
                                        });
                                }
                                first_hop_targets.insert(chan.remote_network_id, (short_channel_id, chan.counterparty_features.clone()));
@@ -1032,7 +1055,7 @@ impl Router {
                                }
                                res.last_mut().unwrap().fee_msat = final_value_msat;
                                res.last_mut().unwrap().cltv_expiry_delta = final_cltv;
-                               let route = Route { hops: res };
+                               let route = Route { paths: vec![res] };
                                log_trace!(self, "Got route: {}", log_route!(route));
                                return Ok(route);
                        }
@@ -1497,21 +1520,21 @@ mod tests {
 
                { // Simple route to 3 via 2
                        let route = router.get_route(&node3, None, &Vec::new(), 100, 42).unwrap();
-                       assert_eq!(route.hops.len(), 2);
+                       assert_eq!(route.paths[0].len(), 2);
 
-                       assert_eq!(route.hops[0].pubkey, node2);
-                       assert_eq!(route.hops[0].short_channel_id, 2);
-                       assert_eq!(route.hops[0].fee_msat, 100);
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (4 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &id_to_feature_flags!(2));
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &id_to_feature_flags!(2));
+                       assert_eq!(route.paths[0][0].pubkey, node2);
+                       assert_eq!(route.paths[0][0].short_channel_id, 2);
+                       assert_eq!(route.paths[0][0].fee_msat, 100);
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (4 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &id_to_feature_flags!(2));
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &id_to_feature_flags!(2));
 
-                       assert_eq!(route.hops[1].pubkey, node3);
-                       assert_eq!(route.hops[1].short_channel_id, 4);
-                       assert_eq!(route.hops[1].fee_msat, 100);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &id_to_feature_flags!(3));
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &id_to_feature_flags!(4));
+                       assert_eq!(route.paths[0][1].pubkey, node3);
+                       assert_eq!(route.paths[0][1].short_channel_id, 4);
+                       assert_eq!(route.paths[0][1].fee_msat, 100);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags!(4));
                }
 
                { // Disable channels 4 and 12 by requiring unknown feature bits
@@ -1539,21 +1562,21 @@ mod tests {
                                is_live: true,
                        }];
                        let route = router.get_route(&node3, Some(&our_chans), &Vec::new(), 100, 42).unwrap();
-                       assert_eq!(route.hops.len(), 2);
+                       assert_eq!(route.paths[0].len(), 2);
 
-                       assert_eq!(route.hops[0].pubkey, node8);
-                       assert_eq!(route.hops[0].short_channel_id, 42);
-                       assert_eq!(route.hops[0].fee_msat, 200);
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (13 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &vec![0b11]); // it should also override our view of their features
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion
+                       assert_eq!(route.paths[0][0].pubkey, node8);
+                       assert_eq!(route.paths[0][0].short_channel_id, 42);
+                       assert_eq!(route.paths[0][0].fee_msat, 200);
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (13 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &vec![0b11]); // it should also override our view of their features
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion
 
-                       assert_eq!(route.hops[1].pubkey, node3);
-                       assert_eq!(route.hops[1].short_channel_id, 13);
-                       assert_eq!(route.hops[1].fee_msat, 100);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &id_to_feature_flags!(3));
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &id_to_feature_flags!(13));
+                       assert_eq!(route.paths[0][1].pubkey, node3);
+                       assert_eq!(route.paths[0][1].short_channel_id, 13);
+                       assert_eq!(route.paths[0][1].fee_msat, 100);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags!(13));
                }
 
                { // Re-enable channels 4 and 12 by wiping the unknown feature bits
@@ -1588,21 +1611,21 @@ mod tests {
                                is_live: true,
                        }];
                        let route = router.get_route(&node3, Some(&our_chans), &Vec::new(), 100, 42).unwrap();
-                       assert_eq!(route.hops.len(), 2);
+                       assert_eq!(route.paths[0].len(), 2);
 
-                       assert_eq!(route.hops[0].pubkey, node8);
-                       assert_eq!(route.hops[0].short_channel_id, 42);
-                       assert_eq!(route.hops[0].fee_msat, 200);
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (13 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &vec![0b11]); // it should also override our view of their features
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion
+                       assert_eq!(route.paths[0][0].pubkey, node8);
+                       assert_eq!(route.paths[0][0].short_channel_id, 42);
+                       assert_eq!(route.paths[0][0].fee_msat, 200);
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (13 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &vec![0b11]); // it should also override our view of their features
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion
 
-                       assert_eq!(route.hops[1].pubkey, node3);
-                       assert_eq!(route.hops[1].short_channel_id, 13);
-                       assert_eq!(route.hops[1].fee_msat, 100);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &id_to_feature_flags!(3));
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &id_to_feature_flags!(13));
+                       assert_eq!(route.paths[0][1].pubkey, node3);
+                       assert_eq!(route.paths[0][1].short_channel_id, 13);
+                       assert_eq!(route.paths[0][1].fee_msat, 100);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags!(13));
                }
 
                { // Re-enable nodes 1, 2, and 8
@@ -1618,28 +1641,28 @@ mod tests {
 
                { // Route to 1 via 2 and 3 because our channel to 1 is disabled
                        let route = router.get_route(&node1, None, &Vec::new(), 100, 42).unwrap();
-                       assert_eq!(route.hops.len(), 3);
-
-                       assert_eq!(route.hops[0].pubkey, node2);
-                       assert_eq!(route.hops[0].short_channel_id, 2);
-                       assert_eq!(route.hops[0].fee_msat, 200);
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (4 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &id_to_feature_flags!(2));
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &id_to_feature_flags!(2));
-
-                       assert_eq!(route.hops[1].pubkey, node3);
-                       assert_eq!(route.hops[1].short_channel_id, 4);
-                       assert_eq!(route.hops[1].fee_msat, 100);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, (3 << 8) | 2);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &id_to_feature_flags!(3));
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &id_to_feature_flags!(4));
-
-                       assert_eq!(route.hops[2].pubkey, node1);
-                       assert_eq!(route.hops[2].short_channel_id, 3);
-                       assert_eq!(route.hops[2].fee_msat, 100);
-                       assert_eq!(route.hops[2].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[2].node_features.le_flags(), &id_to_feature_flags!(1));
-                       assert_eq!(route.hops[2].channel_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0].len(), 3);
+
+                       assert_eq!(route.paths[0][0].pubkey, node2);
+                       assert_eq!(route.paths[0][0].short_channel_id, 2);
+                       assert_eq!(route.paths[0][0].fee_msat, 200);
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (4 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &id_to_feature_flags!(2));
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &id_to_feature_flags!(2));
+
+                       assert_eq!(route.paths[0][1].pubkey, node3);
+                       assert_eq!(route.paths[0][1].short_channel_id, 4);
+                       assert_eq!(route.paths[0][1].fee_msat, 100);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, (3 << 8) | 2);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags!(4));
+
+                       assert_eq!(route.paths[0][2].pubkey, node1);
+                       assert_eq!(route.paths[0][2].short_channel_id, 3);
+                       assert_eq!(route.paths[0][2].fee_msat, 100);
+                       assert_eq!(route.paths[0][2].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][2].node_features.le_flags(), &id_to_feature_flags!(1));
+                       assert_eq!(route.paths[0][2].channel_features.le_flags(), &id_to_feature_flags!(3));
                }
 
                { // If we specify a channel to node8, that overrides our local channel view and that gets used
@@ -1655,21 +1678,21 @@ mod tests {
                                is_live: true,
                        }];
                        let route = router.get_route(&node3, Some(&our_chans), &Vec::new(), 100, 42).unwrap();
-                       assert_eq!(route.hops.len(), 2);
+                       assert_eq!(route.paths[0].len(), 2);
 
-                       assert_eq!(route.hops[0].pubkey, node8);
-                       assert_eq!(route.hops[0].short_channel_id, 42);
-                       assert_eq!(route.hops[0].fee_msat, 200);
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (13 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &vec![0b11]);
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion
+                       assert_eq!(route.paths[0][0].pubkey, node8);
+                       assert_eq!(route.paths[0][0].short_channel_id, 42);
+                       assert_eq!(route.paths[0][0].fee_msat, 200);
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (13 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &vec![0b11]);
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion
 
-                       assert_eq!(route.hops[1].pubkey, node3);
-                       assert_eq!(route.hops[1].short_channel_id, 13);
-                       assert_eq!(route.hops[1].fee_msat, 100);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &id_to_feature_flags!(3));
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &id_to_feature_flags!(13));
+                       assert_eq!(route.paths[0][1].pubkey, node3);
+                       assert_eq!(route.paths[0][1].short_channel_id, 13);
+                       assert_eq!(route.paths[0][1].fee_msat, 100);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags!(13));
                }
 
                let mut last_hops = vec!(RouteHint {
@@ -1697,44 +1720,44 @@ mod tests {
 
                { // Simple test across 2, 3, 5, and 4 via a last_hop channel
                        let route = router.get_route(&node7, None, &last_hops, 100, 42).unwrap();
-                       assert_eq!(route.hops.len(), 5);
-
-                       assert_eq!(route.hops[0].pubkey, node2);
-                       assert_eq!(route.hops[0].short_channel_id, 2);
-                       assert_eq!(route.hops[0].fee_msat, 100);
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (4 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &id_to_feature_flags!(2));
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &id_to_feature_flags!(2));
-
-                       assert_eq!(route.hops[1].pubkey, node3);
-                       assert_eq!(route.hops[1].short_channel_id, 4);
-                       assert_eq!(route.hops[1].fee_msat, 0);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, (6 << 8) | 1);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &id_to_feature_flags!(3));
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &id_to_feature_flags!(4));
-
-                       assert_eq!(route.hops[2].pubkey, node5);
-                       assert_eq!(route.hops[2].short_channel_id, 6);
-                       assert_eq!(route.hops[2].fee_msat, 0);
-                       assert_eq!(route.hops[2].cltv_expiry_delta, (11 << 8) | 1);
-                       assert_eq!(route.hops[2].node_features.le_flags(), &id_to_feature_flags!(5));
-                       assert_eq!(route.hops[2].channel_features.le_flags(), &id_to_feature_flags!(6));
-
-                       assert_eq!(route.hops[3].pubkey, node4);
-                       assert_eq!(route.hops[3].short_channel_id, 11);
-                       assert_eq!(route.hops[3].fee_msat, 0);
-                       assert_eq!(route.hops[3].cltv_expiry_delta, (8 << 8) | 1);
+                       assert_eq!(route.paths[0].len(), 5);
+
+                       assert_eq!(route.paths[0][0].pubkey, node2);
+                       assert_eq!(route.paths[0][0].short_channel_id, 2);
+                       assert_eq!(route.paths[0][0].fee_msat, 100);
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (4 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &id_to_feature_flags!(2));
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &id_to_feature_flags!(2));
+
+                       assert_eq!(route.paths[0][1].pubkey, node3);
+                       assert_eq!(route.paths[0][1].short_channel_id, 4);
+                       assert_eq!(route.paths[0][1].fee_msat, 0);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, (6 << 8) | 1);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags!(4));
+
+                       assert_eq!(route.paths[0][2].pubkey, node5);
+                       assert_eq!(route.paths[0][2].short_channel_id, 6);
+                       assert_eq!(route.paths[0][2].fee_msat, 0);
+                       assert_eq!(route.paths[0][2].cltv_expiry_delta, (11 << 8) | 1);
+                       assert_eq!(route.paths[0][2].node_features.le_flags(), &id_to_feature_flags!(5));
+                       assert_eq!(route.paths[0][2].channel_features.le_flags(), &id_to_feature_flags!(6));
+
+                       assert_eq!(route.paths[0][3].pubkey, node4);
+                       assert_eq!(route.paths[0][3].short_channel_id, 11);
+                       assert_eq!(route.paths[0][3].fee_msat, 0);
+                       assert_eq!(route.paths[0][3].cltv_expiry_delta, (8 << 8) | 1);
                        // If we have a peer in the node map, we'll use their features here since we don't have
                        // a way of figuring out their features from the invoice:
-                       assert_eq!(route.hops[3].node_features.le_flags(), &id_to_feature_flags!(4));
-                       assert_eq!(route.hops[3].channel_features.le_flags(), &id_to_feature_flags!(11));
+                       assert_eq!(route.paths[0][3].node_features.le_flags(), &id_to_feature_flags!(4));
+                       assert_eq!(route.paths[0][3].channel_features.le_flags(), &id_to_feature_flags!(11));
 
-                       assert_eq!(route.hops[4].pubkey, node7);
-                       assert_eq!(route.hops[4].short_channel_id, 8);
-                       assert_eq!(route.hops[4].fee_msat, 100);
-                       assert_eq!(route.hops[4].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[4].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet
-                       assert_eq!(route.hops[4].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly
+                       assert_eq!(route.paths[0][4].pubkey, node7);
+                       assert_eq!(route.paths[0][4].short_channel_id, 8);
+                       assert_eq!(route.paths[0][4].fee_msat, 100);
+                       assert_eq!(route.paths[0][4].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][4].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet
+                       assert_eq!(route.paths[0][4].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly
                }
 
                { // Simple test with outbound channel to 4 to test that last_hops and first_hops connect
@@ -1750,100 +1773,100 @@ mod tests {
                                is_live: true,
                        }];
                        let route = router.get_route(&node7, Some(&our_chans), &last_hops, 100, 42).unwrap();
-                       assert_eq!(route.hops.len(), 2);
+                       assert_eq!(route.paths[0].len(), 2);
 
-                       assert_eq!(route.hops[0].pubkey, node4);
-                       assert_eq!(route.hops[0].short_channel_id, 42);
-                       assert_eq!(route.hops[0].fee_msat, 0);
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (8 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &vec![0b11]);
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion
+                       assert_eq!(route.paths[0][0].pubkey, node4);
+                       assert_eq!(route.paths[0][0].short_channel_id, 42);
+                       assert_eq!(route.paths[0][0].fee_msat, 0);
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (8 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &vec![0b11]);
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &Vec::new()); // No feature flags will meet the relevant-to-channel conversion
 
-                       assert_eq!(route.hops[1].pubkey, node7);
-                       assert_eq!(route.hops[1].short_channel_id, 8);
-                       assert_eq!(route.hops[1].fee_msat, 100);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly
+                       assert_eq!(route.paths[0][1].pubkey, node7);
+                       assert_eq!(route.paths[0][1].short_channel_id, 8);
+                       assert_eq!(route.paths[0][1].fee_msat, 100);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly
                }
 
                last_hops[0].fee_base_msat = 1000;
 
                { // Revert to via 6 as the fee on 8 goes up
                        let route = router.get_route(&node7, None, &last_hops, 100, 42).unwrap();
-                       assert_eq!(route.hops.len(), 4);
-
-                       assert_eq!(route.hops[0].pubkey, node2);
-                       assert_eq!(route.hops[0].short_channel_id, 2);
-                       assert_eq!(route.hops[0].fee_msat, 200); // fee increased as its % of value transferred across node
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (4 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &id_to_feature_flags!(2));
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &id_to_feature_flags!(2));
-
-                       assert_eq!(route.hops[1].pubkey, node3);
-                       assert_eq!(route.hops[1].short_channel_id, 4);
-                       assert_eq!(route.hops[1].fee_msat, 100);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, (7 << 8) | 1);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &id_to_feature_flags!(3));
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &id_to_feature_flags!(4));
-
-                       assert_eq!(route.hops[2].pubkey, node6);
-                       assert_eq!(route.hops[2].short_channel_id, 7);
-                       assert_eq!(route.hops[2].fee_msat, 0);
-                       assert_eq!(route.hops[2].cltv_expiry_delta, (10 << 8) | 1);
+                       assert_eq!(route.paths[0].len(), 4);
+
+                       assert_eq!(route.paths[0][0].pubkey, node2);
+                       assert_eq!(route.paths[0][0].short_channel_id, 2);
+                       assert_eq!(route.paths[0][0].fee_msat, 200); // fee increased as its % of value transferred across node
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (4 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &id_to_feature_flags!(2));
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &id_to_feature_flags!(2));
+
+                       assert_eq!(route.paths[0][1].pubkey, node3);
+                       assert_eq!(route.paths[0][1].short_channel_id, 4);
+                       assert_eq!(route.paths[0][1].fee_msat, 100);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, (7 << 8) | 1);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags!(4));
+
+                       assert_eq!(route.paths[0][2].pubkey, node6);
+                       assert_eq!(route.paths[0][2].short_channel_id, 7);
+                       assert_eq!(route.paths[0][2].fee_msat, 0);
+                       assert_eq!(route.paths[0][2].cltv_expiry_delta, (10 << 8) | 1);
                        // If we have a peer in the node map, we'll use their features here since we don't have
                        // a way of figuring out their features from the invoice:
-                       assert_eq!(route.hops[2].node_features.le_flags(), &id_to_feature_flags!(6));
-                       assert_eq!(route.hops[2].channel_features.le_flags(), &id_to_feature_flags!(7));
+                       assert_eq!(route.paths[0][2].node_features.le_flags(), &id_to_feature_flags!(6));
+                       assert_eq!(route.paths[0][2].channel_features.le_flags(), &id_to_feature_flags!(7));
 
-                       assert_eq!(route.hops[3].pubkey, node7);
-                       assert_eq!(route.hops[3].short_channel_id, 10);
-                       assert_eq!(route.hops[3].fee_msat, 100);
-                       assert_eq!(route.hops[3].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[3].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet
-                       assert_eq!(route.hops[3].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly
+                       assert_eq!(route.paths[0][3].pubkey, node7);
+                       assert_eq!(route.paths[0][3].short_channel_id, 10);
+                       assert_eq!(route.paths[0][3].fee_msat, 100);
+                       assert_eq!(route.paths[0][3].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][3].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet
+                       assert_eq!(route.paths[0][3].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly
                }
 
                { // ...but still use 8 for larger payments as 6 has a variable feerate
                        let route = router.get_route(&node7, None, &last_hops, 2000, 42).unwrap();
-                       assert_eq!(route.hops.len(), 5);
-
-                       assert_eq!(route.hops[0].pubkey, node2);
-                       assert_eq!(route.hops[0].short_channel_id, 2);
-                       assert_eq!(route.hops[0].fee_msat, 3000);
-                       assert_eq!(route.hops[0].cltv_expiry_delta, (4 << 8) | 1);
-                       assert_eq!(route.hops[0].node_features.le_flags(), &id_to_feature_flags!(2));
-                       assert_eq!(route.hops[0].channel_features.le_flags(), &id_to_feature_flags!(2));
-
-                       assert_eq!(route.hops[1].pubkey, node3);
-                       assert_eq!(route.hops[1].short_channel_id, 4);
-                       assert_eq!(route.hops[1].fee_msat, 0);
-                       assert_eq!(route.hops[1].cltv_expiry_delta, (6 << 8) | 1);
-                       assert_eq!(route.hops[1].node_features.le_flags(), &id_to_feature_flags!(3));
-                       assert_eq!(route.hops[1].channel_features.le_flags(), &id_to_feature_flags!(4));
-
-                       assert_eq!(route.hops[2].pubkey, node5);
-                       assert_eq!(route.hops[2].short_channel_id, 6);
-                       assert_eq!(route.hops[2].fee_msat, 0);
-                       assert_eq!(route.hops[2].cltv_expiry_delta, (11 << 8) | 1);
-                       assert_eq!(route.hops[2].node_features.le_flags(), &id_to_feature_flags!(5));
-                       assert_eq!(route.hops[2].channel_features.le_flags(), &id_to_feature_flags!(6));
-
-                       assert_eq!(route.hops[3].pubkey, node4);
-                       assert_eq!(route.hops[3].short_channel_id, 11);
-                       assert_eq!(route.hops[3].fee_msat, 1000);
-                       assert_eq!(route.hops[3].cltv_expiry_delta, (8 << 8) | 1);
+                       assert_eq!(route.paths[0].len(), 5);
+
+                       assert_eq!(route.paths[0][0].pubkey, node2);
+                       assert_eq!(route.paths[0][0].short_channel_id, 2);
+                       assert_eq!(route.paths[0][0].fee_msat, 3000);
+                       assert_eq!(route.paths[0][0].cltv_expiry_delta, (4 << 8) | 1);
+                       assert_eq!(route.paths[0][0].node_features.le_flags(), &id_to_feature_flags!(2));
+                       assert_eq!(route.paths[0][0].channel_features.le_flags(), &id_to_feature_flags!(2));
+
+                       assert_eq!(route.paths[0][1].pubkey, node3);
+                       assert_eq!(route.paths[0][1].short_channel_id, 4);
+                       assert_eq!(route.paths[0][1].fee_msat, 0);
+                       assert_eq!(route.paths[0][1].cltv_expiry_delta, (6 << 8) | 1);
+                       assert_eq!(route.paths[0][1].node_features.le_flags(), &id_to_feature_flags!(3));
+                       assert_eq!(route.paths[0][1].channel_features.le_flags(), &id_to_feature_flags!(4));
+
+                       assert_eq!(route.paths[0][2].pubkey, node5);
+                       assert_eq!(route.paths[0][2].short_channel_id, 6);
+                       assert_eq!(route.paths[0][2].fee_msat, 0);
+                       assert_eq!(route.paths[0][2].cltv_expiry_delta, (11 << 8) | 1);
+                       assert_eq!(route.paths[0][2].node_features.le_flags(), &id_to_feature_flags!(5));
+                       assert_eq!(route.paths[0][2].channel_features.le_flags(), &id_to_feature_flags!(6));
+
+                       assert_eq!(route.paths[0][3].pubkey, node4);
+                       assert_eq!(route.paths[0][3].short_channel_id, 11);
+                       assert_eq!(route.paths[0][3].fee_msat, 1000);
+                       assert_eq!(route.paths[0][3].cltv_expiry_delta, (8 << 8) | 1);
                        // If we have a peer in the node map, we'll use their features here since we don't have
                        // a way of figuring out their features from the invoice:
-                       assert_eq!(route.hops[3].node_features.le_flags(), &id_to_feature_flags!(4));
-                       assert_eq!(route.hops[3].channel_features.le_flags(), &id_to_feature_flags!(11));
-
-                       assert_eq!(route.hops[4].pubkey, node7);
-                       assert_eq!(route.hops[4].short_channel_id, 8);
-                       assert_eq!(route.hops[4].fee_msat, 2000);
-                       assert_eq!(route.hops[4].cltv_expiry_delta, 42);
-                       assert_eq!(route.hops[4].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet
-                       assert_eq!(route.hops[4].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly
+                       assert_eq!(route.paths[0][3].node_features.le_flags(), &id_to_feature_flags!(4));
+                       assert_eq!(route.paths[0][3].channel_features.le_flags(), &id_to_feature_flags!(11));
+
+                       assert_eq!(route.paths[0][4].pubkey, node7);
+                       assert_eq!(route.paths[0][4].short_channel_id, 8);
+                       assert_eq!(route.paths[0][4].fee_msat, 2000);
+                       assert_eq!(route.paths[0][4].cltv_expiry_delta, 42);
+                       assert_eq!(route.paths[0][4].node_features.le_flags(), &Vec::new()); // We dont pass flags in from invoices yet
+                       assert_eq!(route.paths[0][4].channel_features.le_flags(), &Vec::new()); // We can't learn any flags from invoices, sadly
                }
 
                { // Test Router serialization/deserialization
index 420d2fefad31ed1b20044be9aea70864a57cabb5..2c00a133575d60d9923f1e9afb0501b9cc4fa706 100644 (file)
@@ -6,7 +6,7 @@
 //! few other things.
 
 use ln::msgs;
-use ln::channelmanager::{PaymentPreimage, PaymentHash};
+use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret};
 use chain::transaction::OutPoint;
 use chain::keysinterface::SpendableOutputDescriptor;
 use util::ser::{Writeable, Writer, MaybeReadable, Readable};
@@ -58,6 +58,16 @@ pub enum Event {
        PaymentReceived {
                /// The hash for which the preimage should be handed to the ChannelManager.
                payment_hash: PaymentHash,
+               /// The "payment secret". This authenticates the sender to the recipient, preventing a
+               /// number of deanonymization attacks during the routing process.
+               /// As nodes upgrade, the invoices you provide should likely migrate to setting the
+               /// payment_secret feature to required, at which point you should fail_backwards any HTLCs
+               /// which have a None here.
+               /// Until then, however, values of None should be ignored, and only incorrect Some values
+               /// should result in an HTLC fail_backwards.
+               /// Note that, in any case, this value must be passed as-is to any fail or claim calls as
+               /// the HTLC index includes this value.
+               payment_secret: Option<PaymentSecret>,
                /// The value, in thousandths of a satoshi, that this payment is for. Note that you must
                /// compare this to the expected value before accepting the payment (as otherwise you are
                /// providing proof-of-payment for less than the value you expected!).
@@ -119,9 +129,10 @@ impl Writeable for Event {
                                funding_txo.write(writer)?;
                                user_channel_id.write(writer)?;
                        },
-                       &Event::PaymentReceived { ref payment_hash, ref amt } => {
+                       &Event::PaymentReceived { ref payment_hash, ref payment_secret, ref amt } => {
                                2u8.write(writer)?;
                                payment_hash.write(writer)?;
+                               payment_secret.write(writer)?;
                                amt.write(writer)?;
                        },
                        &Event::PaymentSent { ref payment_preimage } => {
@@ -164,6 +175,7 @@ impl MaybeReadable for Event {
                                })),
                        2u8 => Ok(Some(Event::PaymentReceived {
                                        payment_hash: Readable::read(reader)?,
+                                       payment_secret: Readable::read(reader)?,
                                        amt: Readable::read(reader)?,
                                })),
                        3u8 => Ok(Some(Event::PaymentSent {
index d16bd48aebb53a77ca39dbb935b36fb4104560fc..1f9cb1ad27e62d21f916272be115deca7d26710d 100644 (file)
@@ -73,8 +73,11 @@ macro_rules! log_funding_info {
 pub(crate) struct DebugRoute<'a>(pub &'a Route);
 impl<'a> std::fmt::Display for DebugRoute<'a> {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
-               for h in self.0.hops.iter() {
-                       write!(f, "node_id: {}, short_channel_id: {}, fee_msat: {}, cltv_expiry_delta: {}\n", log_pubkey!(h.pubkey), h.short_channel_id, h.fee_msat, h.cltv_expiry_delta)?;
+               for (idx, p) in self.0.paths.iter().enumerate() {
+                       write!(f, "path {}:\n", idx)?;
+                       for h in p.iter() {
+                               write!(f, " node_id: {}, short_channel_id: {}, fee_msat: {}, cltv_expiry_delta: {}\n", log_pubkey!(h.pubkey), h.short_channel_id, h.fee_msat, h.cltv_expiry_delta)?;
+                       }
                }
                Ok(())
        }
index 60d5329d781c8ed247a36eef791470e224878d48..5a68f7a5eb4164a43753630d4e7015b712ac2f37 100644 (file)
@@ -17,7 +17,7 @@ use bitcoin::consensus::Encodable;
 use bitcoin_hashes::sha256d::Hash as Sha256dHash;
 use std::marker::Sized;
 use ln::msgs::DecodeError;
-use ln::channelmanager::{PaymentPreimage, PaymentHash};
+use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret};
 use util::byte_utils;
 
 use util::byte_utils::{be64_to_array, be48_to_array, be32_to_array, be16_to_array, slice_to_be16, slice_to_be32, slice_to_be48, slice_to_be64};
@@ -591,6 +591,19 @@ impl Readable for PaymentHash {
        }
 }
 
+impl Writeable for PaymentSecret {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+               self.0.write(w)
+       }
+}
+
+impl Readable for PaymentSecret {
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let buf: [u8; 32] = Readable::read(r)?;
+               Ok(PaymentSecret(buf))
+       }
+}
+
 impl<T: Writeable> Writeable for Option<T> {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
                match *self {