|
4 | 4 | //! here. See also the chanmon_fail_consistency fuzz test.
|
5 | 5 |
|
6 | 6 | use chain::transaction::OutPoint;
|
7 |
| -use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSendFailure}; |
| 7 | +use ln::channelmanager::{RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure}; |
8 | 8 | use ln::channelmonitor::ChannelMonitorUpdateErr;
|
9 | 9 | use ln::features::InitFeatures;
|
10 | 10 | use ln::msgs;
|
@@ -1731,3 +1731,63 @@ fn during_funding_monitor_fail() {
|
1731 | 1731 | do_during_funding_monitor_fail(true, false);
|
1732 | 1732 | do_during_funding_monitor_fail(false, false);
|
1733 | 1733 | }
|
| 1734 | + |
| 1735 | +#[test] |
| 1736 | +fn test_path_paused_mpp() { |
| 1737 | + // Simple test of sending a multi-part payment where one path is currently blocked awaiting |
| 1738 | + // monitor update |
| 1739 | + let chanmon_cfgs = create_chanmon_cfgs(4); |
| 1740 | + let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); |
| 1741 | + let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); |
| 1742 | + let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs); |
| 1743 | + |
| 1744 | + let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id; |
| 1745 | + let (chan_2_ann, _, chan_2_id, _) = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::supported(), InitFeatures::supported()); |
| 1746 | + let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id; |
| 1747 | + let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::supported(), InitFeatures::supported()).0.contents.short_channel_id; |
| 1748 | + |
| 1749 | + let (payment_preimage, payment_hash) = get_payment_preimage_hash!(&nodes[0]); |
| 1750 | + let payment_secret = PaymentSecret([0xdb; 32]); |
| 1751 | + let mut route = nodes[0].router.get_route(&nodes[3].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); |
| 1752 | + |
| 1753 | + // Set us up to take multiple routes, one 0 -> 1 -> 3 and one 0 -> 2 -> 3: |
| 1754 | + let path = route.paths[0].clone(); |
| 1755 | + route.paths.push(path); |
| 1756 | + route.paths[0][0].pubkey = nodes[1].node.get_our_node_id(); |
| 1757 | + route.paths[0][0].short_channel_id = chan_1_id; |
| 1758 | + route.paths[0][1].short_channel_id = chan_3_id; |
| 1759 | + route.paths[1][0].pubkey = nodes[2].node.get_our_node_id(); |
| 1760 | + route.paths[1][0].short_channel_id = chan_2_ann.contents.short_channel_id; |
| 1761 | + route.paths[1][1].short_channel_id = chan_4_id; |
| 1762 | + |
| 1763 | + // Set it so that the first monitor update (for the path 0 -> 1 -> 3) succeeds, but the second |
| 1764 | + // (for the path 0 -> 2 -> 3) fails. |
| 1765 | + *nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(()); |
| 1766 | + *nodes[0].chan_monitor.next_update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure)); |
| 1767 | + |
| 1768 | + // Now check that we get the right return value, indicating that the first path succeeded but |
| 1769 | + // the second got a MonitorUpdateFailed err. This implies PaymentSendFailure::PartialFailure as |
| 1770 | + // some paths succeeded, preventing retry. |
| 1771 | + if let Err(PaymentSendFailure::PartialFailure(results)) = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)) { |
| 1772 | + assert_eq!(results.len(), 2); |
| 1773 | + if let Ok(()) = results[0] {} else { panic!(); } |
| 1774 | + if let Err(APIError::MonitorUpdateFailed) = results[1] {} else { panic!(); } |
| 1775 | + } else { panic!(); } |
| 1776 | + check_added_monitors!(nodes[0], 2); |
| 1777 | + *nodes[0].chan_monitor.update_ret.lock().unwrap() = Ok(()); |
| 1778 | + |
| 1779 | + // Pass the first HTLC of the payment along to nodes[3]. |
| 1780 | + let mut events = nodes[0].node.get_and_clear_pending_msg_events(); |
| 1781 | + assert_eq!(events.len(), 1); |
| 1782 | + pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 0, payment_hash.clone(), Some(payment_secret), events.pop().unwrap(), false); |
| 1783 | + |
| 1784 | + // And check that, after we successfully update the monitor for chan_2 we can pass the second |
| 1785 | + // HTLC along to nodes[3] and claim the whole payment back to nodes[0]. |
| 1786 | + let (outpoint, latest_update) = nodes[0].chan_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_2_id).unwrap().clone(); |
| 1787 | + nodes[0].node.channel_monitor_updated(&outpoint, latest_update); |
| 1788 | + let mut events = nodes[0].node.get_and_clear_pending_msg_events(); |
| 1789 | + assert_eq!(events.len(), 1); |
| 1790 | + pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash.clone(), Some(payment_secret), events.pop().unwrap(), true); |
| 1791 | + |
| 1792 | + claim_payment_along_route_with_secret(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage, Some(payment_secret), 200_000); |
| 1793 | +} |
0 commit comments