+ let node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
+ if recv_count > 0 {
+ nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed).unwrap();
+ let (_, node_1_closing_signed) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
+ assert!(node_1_closing_signed.is_some());
+ }
+
+ 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);
+
+ nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id());
+ let node_0_2nd_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
+ nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
+ if recv_count == 0 {
+ // If all closing_signeds weren't delivered we can just resume where we left off...
+ let node_1_2nd_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
+
+ nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &node_1_2nd_reestablish).unwrap();
+ let node_0_3rd_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
+ assert!(node_0_2nd_shutdown == node_0_3rd_shutdown);
+
+ nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &node_0_2nd_reestablish).unwrap();
+ let node_1_3rd_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
+ assert!(node_1_3rd_shutdown == node_1_2nd_shutdown);
+
+ nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_3rd_shutdown).unwrap();
+ assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
+
+ nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_3rd_shutdown).unwrap();
+ let node_0_2nd_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
+ assert!(node_0_closing_signed == node_0_2nd_closing_signed);
+
+ nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_2nd_closing_signed).unwrap();
+ let (_, node_1_closing_signed) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
+ nodes[0].node.handle_closing_signed(&nodes[1].node.get_our_node_id(), &node_1_closing_signed.unwrap()).unwrap();
+ let (_, node_0_none) = get_closing_signed_broadcast!(nodes[0].node, nodes[1].node.get_our_node_id());
+ assert!(node_0_none.is_none());
+ } else {
+ // If one node, however, received + responded with an identical closing_signed we end
+ // up erroring and node[0] will try to broadcast its own latest commitment transaction.
+ // There isn't really anything better we can do simply, but in the future we might
+ // explore storing a set of recently-closed channels that got disconnected during
+ // closing_signed and avoiding broadcasting local commitment txn for some timeout to
+ // give our counterparty enough time to (potentially) broadcast a cooperative closing
+ // transaction.
+ assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
+
+ if let Err(msgs::HandleError{action: Some(msgs::ErrorAction::SendErrorMessage{msg}), ..}) =
+ nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &node_0_2nd_reestablish) {
+ nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msg);
+ let msgs::ErrorMessage {ref channel_id, ..} = msg;
+ assert_eq!(*channel_id, chan_1.2);
+ } else { panic!("Needed SendErrorMessage close"); }
+
+ // get_closing_signed_broadcast usually eats the BroadcastChannelUpdate for us and
+ // checks it, but in this case nodes[0] didn't ever get a chance to receive a
+ // closing_signed so we do it ourselves
+ let events = nodes[0].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
+ assert_eq!(msg.contents.flags & 2, 2);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ }
+
+ assert!(nodes[0].node.list_channels().is_empty());
+
+ assert_eq!(nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
+ nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clear();
+ close_channel(&nodes[1], &nodes[2], &chan_2.2, chan_2.3, true);
+ assert!(nodes[1].node.list_channels().is_empty());
+ assert!(nodes[2].node.list_channels().is_empty());
+ }
+
+ #[test]
+ fn test_shutdown_rebroadcast() {
+ do_test_shutdown_rebroadcast(0);
+ do_test_shutdown_rebroadcast(1);
+ do_test_shutdown_rebroadcast(2);
+ }
+
+ #[test]
+ fn fake_network_test() {
+ // Simple test which builds a network of ChannelManagers, connects them to each other, and
+ // tests that payments get routed and transactions broadcast in semi-reasonable ways.
+ let nodes = create_network(4);
+
+ // Create some initial channels
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
+
+ // Rebalance the network a bit by relaying one payment through all the channels...
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
+
+ // Send some more payments
+ send_payment(&nodes[1], &vec!(&nodes[2], &nodes[3])[..], 1000000);
+ send_payment(&nodes[3], &vec!(&nodes[2], &nodes[1], &nodes[0])[..], 1000000);
+ send_payment(&nodes[3], &vec!(&nodes[2], &nodes[1])[..], 1000000);
+
+ // Test failure packets
+ let payment_hash_1 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 1000000).1;
+ fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], payment_hash_1);
+
+ // Add a new channel that skips 3
+ let chan_4 = create_announced_chan_between_nodes(&nodes, 1, 3);
+
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 1000000);
+ send_payment(&nodes[2], &vec!(&nodes[3])[..], 1000000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
+
+ // Do some rebalance loop payments, simultaneously
+ let mut hops = Vec::with_capacity(3);
+ hops.push(RouteHop {
+ pubkey: nodes[2].node.get_our_node_id(),
+ short_channel_id: chan_2.0.contents.short_channel_id,
+ fee_msat: 0,
+ cltv_expiry_delta: chan_3.0.contents.cltv_expiry_delta as u32
+ });
+ hops.push(RouteHop {
+ pubkey: nodes[3].node.get_our_node_id(),
+ short_channel_id: chan_3.0.contents.short_channel_id,
+ fee_msat: 0,
+ cltv_expiry_delta: chan_4.1.contents.cltv_expiry_delta as u32
+ });
+ hops.push(RouteHop {
+ pubkey: nodes[1].node.get_our_node_id(),
+ short_channel_id: chan_4.0.contents.short_channel_id,
+ fee_msat: 1000000,
+ cltv_expiry_delta: TEST_FINAL_CLTV,
+ });
+ 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 mut hops = Vec::with_capacity(3);
+ hops.push(RouteHop {
+ pubkey: nodes[3].node.get_our_node_id(),
+ short_channel_id: chan_4.0.contents.short_channel_id,
+ fee_msat: 0,
+ cltv_expiry_delta: chan_3.1.contents.cltv_expiry_delta as u32
+ });
+ hops.push(RouteHop {
+ pubkey: nodes[2].node.get_our_node_id(),
+ short_channel_id: chan_3.0.contents.short_channel_id,
+ fee_msat: 0,
+ cltv_expiry_delta: chan_2.1.contents.cltv_expiry_delta as u32
+ });
+ hops.push(RouteHop {
+ pubkey: nodes[1].node.get_our_node_id(),
+ short_channel_id: chan_2.0.contents.short_channel_id,
+ fee_msat: 1000000,
+ cltv_expiry_delta: TEST_FINAL_CLTV,
+ });
+ 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;
+
+ // Claim the rebalances...
+ fail_payment(&nodes[1], &vec!(&nodes[3], &nodes[2], &nodes[1])[..], payment_hash_2);
+ claim_payment(&nodes[1], &vec!(&nodes[2], &nodes[3], &nodes[1])[..], payment_preimage_1);
+
+ // Add a duplicate new channel from 2 to 4
+ let chan_5 = create_announced_chan_between_nodes(&nodes, 1, 3);
+
+ // Send some payments across both channels
+ let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 3000000).0;
+ let payment_preimage_4 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 3000000).0;
+ let payment_preimage_5 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 3000000).0;
+
+ route_over_limit(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 3000000);
+
+ //TODO: Test that routes work again here as we've been notified that the channel is full
+
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_3);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_4);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_5);
+
+ // Close down the channels...
+ close_channel(&nodes[0], &nodes[1], &chan_1.2, chan_1.3, true);
+ close_channel(&nodes[1], &nodes[2], &chan_2.2, chan_2.3, false);
+ close_channel(&nodes[2], &nodes[3], &chan_3.2, chan_3.3, true);
+ close_channel(&nodes[1], &nodes[3], &chan_4.2, chan_4.3, false);
+ close_channel(&nodes[1], &nodes[3], &chan_5.2, chan_5.3, false);
+ }
+
+ #[test]
+ fn duplicate_htlc_test() {
+ // Test that we accept duplicate payment_hash HTLCs across the network and that
+ // claiming/failing them are all separate and don't effect each other
+ let mut nodes = create_network(6);
+
+ // Create some initial channels to route via 3 to 4/5 from 0/1/2
+ create_announced_chan_between_nodes(&nodes, 0, 3);
+ create_announced_chan_between_nodes(&nodes, 1, 3);
+ create_announced_chan_between_nodes(&nodes, 2, 3);
+ create_announced_chan_between_nodes(&nodes, 3, 4);
+ create_announced_chan_between_nodes(&nodes, 3, 5);
+
+ let (payment_preimage, payment_hash) = route_payment(&nodes[0], &vec!(&nodes[3], &nodes[4])[..], 1000000);
+
+ *nodes[0].network_payment_count.borrow_mut() -= 1;
+ assert_eq!(route_payment(&nodes[1], &vec!(&nodes[3])[..], 1000000).0, payment_preimage);
+
+ *nodes[0].network_payment_count.borrow_mut() -= 1;
+ assert_eq!(route_payment(&nodes[2], &vec!(&nodes[3], &nodes[5])[..], 1000000).0, payment_preimage);
+
+ claim_payment(&nodes[0], &vec!(&nodes[3], &nodes[4])[..], payment_preimage);
+ fail_payment(&nodes[2], &vec!(&nodes[3], &nodes[5])[..], payment_hash);
+ claim_payment(&nodes[1], &vec!(&nodes[3])[..], payment_preimage);
+ }
+
+ #[derive(PartialEq)]
+ enum HTLCType { NONE, TIMEOUT, SUCCESS }
+ /// Tests that the given node has broadcast transactions for the given Channel
+ ///
+ /// First checks that the latest local commitment tx has been broadcast, unless an explicit
+ /// commitment_tx is provided, which may be used to test that a remote commitment tx was
+ /// broadcast and the revoked outputs were claimed.
+ ///
+ /// Next tests that there is (or is not) a transaction that spends the commitment transaction
+ /// that appears to be the type of HTLC transaction specified in has_htlc_tx.
+ ///
+ /// All broadcast transactions must be accounted for in one of the above three types of we'll
+ /// also fail.
+ fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
+ let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
+ assert!(node_txn.len() >= if commitment_tx.is_some() { 0 } else { 1 } + if has_htlc_tx == HTLCType::NONE { 0 } else { 1 });
+
+ let mut res = Vec::with_capacity(2);
+ node_txn.retain(|tx| {
+ if tx.input.len() == 1 && tx.input[0].previous_output.txid == chan.3.txid() {
+ check_spends!(tx, chan.3.clone());
+ if commitment_tx.is_none() {
+ res.push(tx.clone());
+ }
+ false
+ } else { true }
+ });
+ if let Some(explicit_tx) = commitment_tx {
+ res.push(explicit_tx.clone());
+ }
+
+ assert_eq!(res.len(), 1);
+
+ if has_htlc_tx != HTLCType::NONE {
+ node_txn.retain(|tx| {
+ if tx.input.len() == 1 && tx.input[0].previous_output.txid == res[0].txid() {
+ check_spends!(tx, res[0].clone());
+ if has_htlc_tx == HTLCType::TIMEOUT {
+ assert!(tx.lock_time != 0);
+ } else {
+ assert!(tx.lock_time == 0);
+ }
+ res.push(tx.clone());
+ false
+ } else { true }
+ });
+ assert_eq!(res.len(), 2);
+ }
+
+ assert!(node_txn.is_empty());
+ res
+ }
+
+ /// Tests that the given node has broadcast a claim transaction against the provided revoked
+ /// HTLC transaction.
+ fn test_revoked_htlc_claim_txn_broadcast(node: &Node, revoked_tx: Transaction) {
+ let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
+ assert_eq!(node_txn.len(), 1);
+ node_txn.retain(|tx| {
+ if tx.input.len() == 1 && tx.input[0].previous_output.txid == revoked_tx.txid() {
+ check_spends!(tx, revoked_tx.clone());
+ false
+ } else { true }
+ });
+ assert!(node_txn.is_empty());
+ }
+
+ fn check_preimage_claim(node: &Node, prev_txn: &Vec<Transaction>) -> Vec<Transaction> {
+ let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
+
+ assert!(node_txn.len() >= 1);
+ assert_eq!(node_txn[0].input.len(), 1);
+ let mut found_prev = false;
+
+ for tx in prev_txn {
+ if node_txn[0].input[0].previous_output.txid == tx.txid() {
+ check_spends!(node_txn[0], tx.clone());
+ assert!(node_txn[0].input[0].witness[2].len() > 106); // must spend an htlc output
+ assert_eq!(tx.input.len(), 1); // must spend a commitment tx
+
+ found_prev = true;
+ break;
+ }
+ }
+ assert!(found_prev);
+
+ let mut res = Vec::new();
+ mem::swap(&mut *node_txn, &mut res);
+ res
+ }
+
+ fn get_announce_close_broadcast_events(nodes: &Vec<Node>, a: usize, b: usize) {
+ let events_1 = nodes[a].node.get_and_clear_pending_msg_events();
+ assert_eq!(events_1.len(), 1);
+ let as_update = match events_1[0] {
+ MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
+ msg.clone()
+ },
+ _ => panic!("Unexpected event"),
+ };
+
+ let events_2 = nodes[b].node.get_and_clear_pending_msg_events();
+ assert_eq!(events_2.len(), 1);
+ let bs_update = match events_2[0] {
+ MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
+ msg.clone()
+ },
+ _ => panic!("Unexpected event"),
+ };
+
+ for node in nodes {
+ node.router.handle_channel_update(&as_update).unwrap();
+ node.router.handle_channel_update(&bs_update).unwrap();
+ }
+ }
+
+ macro_rules! expect_pending_htlcs_forwardable {
+ ($node: expr) => {{
+ let events = $node.node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ Event::PendingHTLCsForwardable { .. } => { },
+ _ => panic!("Unexpected event"),
+ };
+ $node.node.channel_state.lock().unwrap().next_forward = Instant::now();
+ $node.node.process_pending_htlc_forwards();
+ }}
+ }
+
+ #[test]
+ fn channel_reserve_test() {
+ use util::rng;
+ use std::sync::atomic::Ordering;
+ use ln::msgs::HandleError;
+
+ macro_rules! get_channel_value_stat {
+ ($node: expr, $channel_id: expr) => {{
+ let chan_lock = $node.node.channel_state.lock().unwrap();
+ let chan = chan_lock.by_id.get(&$channel_id).unwrap();
+ chan.get_value_stat()
+ }}
+ }
+
+ let mut nodes = create_network(3);
+ let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1900, 1001);
+ let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1900, 1001);
+
+ let mut stat01 = get_channel_value_stat!(nodes[0], chan_1.2);
+ let mut stat11 = get_channel_value_stat!(nodes[1], chan_1.2);
+
+ let mut stat12 = get_channel_value_stat!(nodes[1], chan_2.2);
+ let mut stat22 = get_channel_value_stat!(nodes[2], chan_2.2);
+
+ macro_rules! get_route_and_payment_hash {
+ ($recv_value: expr) => {{
+ let route = nodes[0].router.get_route(&nodes.last().unwrap().node.get_our_node_id(), None, &Vec::new(), $recv_value, TEST_FINAL_CLTV).unwrap();
+ let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[0]);
+ (route, payment_hash, payment_preimage)
+ }}
+ };
+
+ macro_rules! expect_forward {
+ ($node: expr) => {{
+ let mut events = $node.node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ check_added_monitors!($node, 1);
+ let payment_event = SendEvent::from_event(events.remove(0));
+ payment_event
+ }}
+ }
+
+ macro_rules! expect_payment_received {
+ ($node: expr, $expected_payment_hash: expr, $expected_recv_value: expr) => {
+ let events = $node.node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ Event::PaymentReceived { ref payment_hash, amt } => {
+ assert_eq!($expected_payment_hash, *payment_hash);
+ assert_eq!($expected_recv_value, amt);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ }
+ };
+
+ let feemsat = 239; // somehow we know?
+ let total_fee_msat = (nodes.len() - 2) as u64 * 239;
+
+ let recv_value_0 = stat01.their_max_htlc_value_in_flight_msat - total_fee_msat;
+
+ // 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 our max HTLC value in flight"),
+ _ => panic!("Unknown error variants"),
+ }
+ }
+
+ let mut htlc_id = 0;
+ // channel reserve is bigger than their_max_htlc_value_in_flight_msat so loop to deplete
+ // nodes[0]'s wealth
+ loop {
+ let amt_msat = recv_value_0 + total_fee_msat;
+ if stat01.value_to_self_msat - amt_msat < stat01.channel_reserve_msat {
+ break;
+ }
+ send_payment(&nodes[0], &vec![&nodes[1], &nodes[2]][..], recv_value_0);
+ htlc_id += 1;
+
+ let (stat01_, stat11_, stat12_, stat22_) = (
+ get_channel_value_stat!(nodes[0], chan_1.2),
+ get_channel_value_stat!(nodes[1], chan_1.2),
+ get_channel_value_stat!(nodes[1], chan_2.2),
+ get_channel_value_stat!(nodes[2], chan_2.2),
+ );
+
+ assert_eq!(stat01_.value_to_self_msat, stat01.value_to_self_msat - amt_msat);
+ assert_eq!(stat11_.value_to_self_msat, stat11.value_to_self_msat + amt_msat);
+ assert_eq!(stat12_.value_to_self_msat, stat12.value_to_self_msat - (amt_msat - feemsat));
+ assert_eq!(stat22_.value_to_self_msat, stat22.value_to_self_msat + (amt_msat - feemsat));
+ stat01 = stat01_; stat11 = stat11_; stat12 = stat12_; stat22 = stat22_;
+ }
+
+ {
+ 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 our reserve value"),
+ _ => panic!("Unknown error variants"),
+ }
+ }
+
+ // adding pending output
+ let recv_value_1 = (stat01.value_to_self_msat - stat01.channel_reserve_msat - total_fee_msat)/2;
+ let amt_msat_1 = recv_value_1 + total_fee_msat;
+
+ 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();
+ check_added_monitors!(nodes[0], 1);
+
+ let mut events = nodes[0].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ SendEvent::from_event(events.remove(0))
+ };
+ nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event_1.msgs[0]).unwrap();
+
+ // channel reserve test with htlc pending output > 0
+ 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 our reserve value"),
+ _ => panic!("Unknown error variants"),
+ }
+ }
+
+ {
+ // test channel_reserve test on nodes[1] side
+ let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_2 + 1);
+
+ // Need to manually create update_add_htlc message to go around the channel reserve check in send_htlc()
+ let secp_ctx = Secp256k1::new();
+ let session_priv = SecretKey::from_slice(&secp_ctx, &{
+ let mut session_key = [0; 32];
+ rng::fill_bytes(&mut session_key);
+ session_key
+ }).expect("RNG is bad!");
+
+ let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
+ let onion_keys = ChannelManager::construct_onion_keys(&secp_ctx, &route, &session_priv).unwrap();
+ let (onion_payloads, htlc_msat, htlc_cltv) = ChannelManager::build_onion_payloads(&route, cur_height).unwrap();
+ let onion_packet = ChannelManager::construct_onion_packet(onion_payloads, onion_keys, &our_payment_hash);
+ let msg = msgs::UpdateAddHTLC {
+ channel_id: chan_1.2,
+ htlc_id,
+ amount_msat: htlc_msat,
+ payment_hash: our_payment_hash,
+ cltv_expiry: htlc_cltv,
+ onion_routing_packet: onion_packet,
+ };
+
+ let err = nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &msg).err().unwrap();
+ match err {
+ HandleError{err, .. } => assert_eq!(err, "Remote HTLC add would put them over their reserve value"),
+ }
+ }
+
+ // split the rest to test holding cell
+ let recv_value_21 = recv_value_2/2;
+ let recv_value_22 = recv_value_2 - recv_value_21 - total_fee_msat;
+ {
+ let stat = get_channel_value_stat!(nodes[0], chan_1.2);
+ assert_eq!(stat.value_to_self_msat - (stat.pending_outbound_htlcs_amount_msat + recv_value_21 + recv_value_22 + total_fee_msat + total_fee_msat), stat.channel_reserve_msat);
+ }
+
+ // 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();
+ check_added_monitors!(nodes[0], 0);
+ let events = nodes[0].node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 0);
+
+ // 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 our reserve value"),
+ _ => panic!("Unknown error variants"),
+ }
+ }
+
+ 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();
+ 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());
+
+ // flush the pending htlc
+ nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event_1.commitment_msg).unwrap();
+ let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+ check_added_monitors!(nodes[1], 1);
+
+ nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &as_revoke_and_ack).unwrap();
+ check_added_monitors!(nodes[0], 1);
+ let commitment_update_2 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
+
+ nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &as_commitment_signed).unwrap();
+ let bs_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
+ // No commitment_signed so get_event_msg's assert(len == 1) passes
+ check_added_monitors!(nodes[0], 1);
+
+ nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &bs_revoke_and_ack).unwrap();
+ assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
+ check_added_monitors!(nodes[1], 1);
+
+ expect_pending_htlcs_forwardable!(nodes[1]);
+
+ let ref payment_event_11 = expect_forward!(nodes[1]);
+ nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event_11.msgs[0]).unwrap();
+ commitment_signed_dance!(nodes[2], nodes[1], payment_event_11.commitment_msg, false);
+
+ expect_pending_htlcs_forwardable!(nodes[2]);
+ expect_payment_received!(nodes[2], our_payment_hash_1, recv_value_1);
+
+ // flush the htlcs in the holding cell
+ assert_eq!(commitment_update_2.update_add_htlcs.len(), 2);
+ nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &commitment_update_2.update_add_htlcs[0]).unwrap();
+ nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &commitment_update_2.update_add_htlcs[1]).unwrap();
+ commitment_signed_dance!(nodes[1], nodes[0], &commitment_update_2.commitment_signed, false);
+ expect_pending_htlcs_forwardable!(nodes[1]);
+
+ let ref payment_event_3 = expect_forward!(nodes[1]);
+ assert_eq!(payment_event_3.msgs.len(), 2);
+ nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event_3.msgs[0]).unwrap();
+ nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event_3.msgs[1]).unwrap();
+
+ commitment_signed_dance!(nodes[2], nodes[1], &payment_event_3.commitment_msg, false);
+ expect_pending_htlcs_forwardable!(nodes[2]);
+
+ let events = nodes[2].node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 2);
+ match events[0] {
+ Event::PaymentReceived { ref payment_hash, amt } => {
+ assert_eq!(our_payment_hash_21, *payment_hash);
+ assert_eq!(recv_value_21, amt);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ match events[1] {
+ Event::PaymentReceived { ref payment_hash, amt } => {
+ assert_eq!(our_payment_hash_22, *payment_hash);
+ assert_eq!(recv_value_22, amt);
+ },
+ _ => panic!("Unexpected event"),
+ }
+
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_1);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_21);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_22);
+
+ let expected_value_to_self = stat01.value_to_self_msat - (recv_value_1 + total_fee_msat) - (recv_value_21 + total_fee_msat) - (recv_value_22 + total_fee_msat);
+ let stat0 = get_channel_value_stat!(nodes[0], chan_1.2);
+ assert_eq!(stat0.value_to_self_msat, expected_value_to_self);
+ assert_eq!(stat0.value_to_self_msat, stat0.channel_reserve_msat);
+
+ let stat2 = get_channel_value_stat!(nodes[2], chan_2.2);
+ assert_eq!(stat2.value_to_self_msat, stat22.value_to_self_msat + recv_value_1 + recv_value_21 + recv_value_22);
+ }
+
+ #[test]
+ fn channel_monitor_network_test() {
+ // Simple test which builds a network of ChannelManagers, connects them to each other, and
+ // tests that ChannelMonitor is able to recover from various states.
+ let nodes = create_network(5);
+
+ // Create some initial channels
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
+ let chan_4 = create_announced_chan_between_nodes(&nodes, 3, 4);
+
+ // Rebalance the network a bit by relaying one payment through all the channels...
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+
+ // Simple case with no pending HTLCs:
+ nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true);
+ {
+ let mut node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE);
+ let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
+ test_txn_broadcast(&nodes[0], &chan_1, None, HTLCType::NONE);
+ }
+ get_announce_close_broadcast_events(&nodes, 0, 1);
+ assert_eq!(nodes[0].node.list_channels().len(), 0);
+ assert_eq!(nodes[1].node.list_channels().len(), 1);
+
+ // One pending HTLC is discarded by the force-close:
+ let payment_preimage_1 = route_payment(&nodes[1], &vec!(&nodes[2], &nodes[3])[..], 3000000).0;
+
+ // Simple case of one pending HTLC to HTLC-Timeout
+ nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true);
+ {
+ let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT);
+ let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
+ test_txn_broadcast(&nodes[2], &chan_2, None, HTLCType::NONE);
+ }
+ get_announce_close_broadcast_events(&nodes, 1, 2);
+ assert_eq!(nodes[1].node.list_channels().len(), 0);
+ assert_eq!(nodes[2].node.list_channels().len(), 1);
+
+ macro_rules! claim_funds {
+ ($node: expr, $prev_node: expr, $preimage: expr) => {
+ {
+ assert!($node.node.claim_funds($preimage));
+ check_added_monitors!($node, 1);
+
+ 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_fail_htlcs, .. } } => {
+ assert!(update_add_htlcs.is_empty());
+ assert!(update_fail_htlcs.is_empty());
+ assert_eq!(*node_id, $prev_node.node.get_our_node_id());
+ },
+ _ => panic!("Unexpected event"),
+ };
+ }
+ }
+ }
+
+ // nodes[3] gets the preimage, but nodes[2] already disconnected, resulting in a nodes[2]
+ // HTLC-Timeout and a nodes[3] claim against it (+ its own announces)
+ nodes[2].node.peer_disconnected(&nodes[3].node.get_our_node_id(), true);
+ {
+ let node_txn = test_txn_broadcast(&nodes[2], &chan_3, None, HTLCType::TIMEOUT);
+
+ // Claim the payment on nodes[3], giving it knowledge of the preimage
+ claim_funds!(nodes[3], nodes[2], payment_preimage_1);
+
+ let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[3].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, 1);
+
+ check_preimage_claim(&nodes[3], &node_txn);
+ }
+ get_announce_close_broadcast_events(&nodes, 2, 3);
+ assert_eq!(nodes[2].node.list_channels().len(), 0);
+ assert_eq!(nodes[3].node.list_channels().len(), 1);
+
+ { // Cheat and reset nodes[4]'s height to 1
+ let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[4].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![] }, 1);
+ }
+
+ assert_eq!(nodes[3].node.latest_block_height.load(Ordering::Acquire), 1);
+ assert_eq!(nodes[4].node.latest_block_height.load(Ordering::Acquire), 1);
+ // One pending HTLC to time out:
+ let payment_preimage_2 = route_payment(&nodes[3], &vec!(&nodes[4])[..], 3000000).0;
+ // CLTV expires at TEST_FINAL_CLTV + 1 (current height) + 1 (added in send_payment for
+ // buffer space).
+
+ {
+ let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[3].chain_monitor.block_connected_checked(&header, 2, &Vec::new()[..], &[0; 0]);
+ for i in 3..TEST_FINAL_CLTV + 2 + HTLC_FAIL_TIMEOUT_BLOCKS + 1 {
+ header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[3].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
+ }
+
+ let node_txn = test_txn_broadcast(&nodes[3], &chan_4, None, HTLCType::TIMEOUT);
+
+ // Claim the payment on nodes[4], giving it knowledge of the preimage
+ claim_funds!(nodes[4], nodes[3], payment_preimage_2);
+
+ header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[4].chain_monitor.block_connected_checked(&header, 2, &Vec::new()[..], &[0; 0]);
+ for i in 3..TEST_FINAL_CLTV + 2 - CLTV_CLAIM_BUFFER + 1 {
+ header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[4].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
+ }
+
+ test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS);
+
+ header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[4].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, TEST_FINAL_CLTV - 5);
+
+ check_preimage_claim(&nodes[4], &node_txn);
+ }
+ get_announce_close_broadcast_events(&nodes, 3, 4);
+ assert_eq!(nodes[3].node.list_channels().len(), 0);
+ assert_eq!(nodes[4].node.list_channels().len(), 0);
+ }
+
+ #[test]
+ fn test_justice_tx() {
+ // Test justice txn built on revoked HTLC-Success tx, against both sides
+
+ let nodes = create_network(2);
+ // Create some new channels:
+ let chan_5 = create_announced_chan_between_nodes(&nodes, 0, 1);
+
+ // A pending HTLC which will be revoked:
+ let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
+ // Get the will-be-revoked local txn from nodes[0]
+ let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.iter().next().unwrap().1.last_local_commitment_txn.clone();
+ assert_eq!(revoked_local_txn.len(), 2); // First commitment tx, then HTLC tx
+ assert_eq!(revoked_local_txn[0].input.len(), 1);
+ assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_5.3.txid());
+ assert_eq!(revoked_local_txn[0].output.len(), 2); // Only HTLC and output back to 0 are present
+ assert_eq!(revoked_local_txn[1].input.len(), 1);
+ assert_eq!(revoked_local_txn[1].input[0].previous_output.txid, revoked_local_txn[0].txid());
+ assert_eq!(revoked_local_txn[1].input[0].witness.last().unwrap().len(), 133); // HTLC-Timeout
+ // Revoke the old state
+ claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_3);
+
+ {
+ let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
+ {
+ let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+ assert_eq!(node_txn.len(), 3);
+ assert_eq!(node_txn.pop().unwrap(), node_txn[0]); // An outpoint registration will result in a 2nd block_connected
+ assert_eq!(node_txn[0].input.len(), 2); // We should claim the revoked output and the HTLC output
+
+ check_spends!(node_txn[0], revoked_local_txn[0].clone());
+ node_txn.swap_remove(0);
+ }
+ test_txn_broadcast(&nodes[1], &chan_5, None, HTLCType::NONE);