- // If we delievered B's RAA we got an unknown preimage error, not something
- // that we should update our routing table for.
- assert_eq!(events.len(), if deliver_bs_raa { 2 } else { 3 });
- for event in events {
- match event {
- MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
- _ => panic!("Unexpected event"),
- }
- }
- let events = nodes[0].node.get_and_clear_pending_events();
- assert_eq!(events.len(), 3);
- match events[0] {
- Event::PaymentFailed { ref payment_hash, .. } => {
- assert!(failed_htlcs.insert(payment_hash.0));
- },
- _ => panic!("Unexpected event"),
- }
- match events[1] {
- Event::PaymentFailed { ref payment_hash, .. } => {
- assert!(failed_htlcs.insert(payment_hash.0));
- },
- _ => panic!("Unexpected event"),
- }
- match events[2] {
- Event::PaymentFailed { ref payment_hash, .. } => {
- assert!(failed_htlcs.insert(payment_hash.0));
- },
- _ => panic!("Unexpected event"),
- }
- },
- _ => panic!("Unexpected event"),
- }
-
- assert!(failed_htlcs.contains(&first_payment_hash.0));
- assert!(failed_htlcs.contains(&second_payment_hash.0));
- assert!(failed_htlcs.contains(&third_payment_hash.0));
-}
-
-#[test]
-fn test_commitment_revoked_fail_backward_exhaustive_a() {
- do_test_commitment_revoked_fail_backward_exhaustive(false, true, false);
- do_test_commitment_revoked_fail_backward_exhaustive(true, true, false);
- do_test_commitment_revoked_fail_backward_exhaustive(false, false, false);
- do_test_commitment_revoked_fail_backward_exhaustive(true, false, false);
-}
-
-#[test]
-fn test_commitment_revoked_fail_backward_exhaustive_b() {
- do_test_commitment_revoked_fail_backward_exhaustive(false, true, true);
- do_test_commitment_revoked_fail_backward_exhaustive(true, true, true);
- do_test_commitment_revoked_fail_backward_exhaustive(false, false, true);
- do_test_commitment_revoked_fail_backward_exhaustive(true, false, true);
-}
-
-#[test]
-fn test_htlc_ignore_latest_remote_commitment() {
- // Test that HTLC transactions spending the latest remote commitment transaction are simply
- // ignored if we cannot claim them. This originally tickled an invalid unwrap().
- let nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
-
- route_payment(&nodes[0], &[&nodes[1]], 10000000);
- nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id);
- check_closed_broadcast!(nodes[0]);
-
- let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
- assert_eq!(node_txn.len(), 2);
-
- let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
- nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0], &node_txn[1]], &[1; 2]);
- check_closed_broadcast!(nodes[1]);
-
- // Duplicate the block_connected call since this may happen due to other listeners
- // registering new transactions
- nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0], &node_txn[1]], &[1; 2]);
-}
-
-#[test]
-fn test_force_close_fail_back() {
- // Check which HTLCs are failed-backwards on channel force-closure
- let mut nodes = create_network(3);
- create_announced_chan_between_nodes(&nodes, 0, 1);
- create_announced_chan_between_nodes(&nodes, 1, 2);
-
- let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, 42).unwrap();
-
- 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();
- 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.msgs[0]).unwrap();
- commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
-
- expect_pending_htlcs_forwardable!(nodes[1]);
-
- let mut events_2 = nodes[1].node.get_and_clear_pending_msg_events();
- assert_eq!(events_2.len(), 1);
- payment_event = SendEvent::from_event(events_2.remove(0));
- assert_eq!(payment_event.msgs.len(), 1);
-
- check_added_monitors!(nodes[1], 1);
- nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]).unwrap();
- nodes[2].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &payment_event.commitment_msg).unwrap();
- check_added_monitors!(nodes[2], 1);
- let (_, _) = get_revoke_commit_msgs!(nodes[2], nodes[1].node.get_our_node_id());
-
- // nodes[2] now has the latest commitment transaction, but hasn't revoked its previous
- // state or updated nodes[1]' state. Now force-close and broadcast that commitment/HTLC
- // transaction and ensure nodes[1] doesn't fail-backwards (this was originally a bug!).
-
- nodes[2].node.force_close_channel(&payment_event.commitment_msg.channel_id);
- check_closed_broadcast!(nodes[2]);
- let tx = {
- let mut node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap();
- // Note that we don't bother broadcasting the HTLC-Success transaction here as we don't
- // have a use for it unless nodes[2] learns the preimage somehow, the funds will go
- // back to nodes[1] upon timeout otherwise.
- assert_eq!(node_txn.len(), 1);
- node_txn.remove(0)
- };
-
- let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
- nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&tx], &[1]);
-
- // Note no UpdateHTLCs event here from nodes[1] to nodes[0]!
- check_closed_broadcast!(nodes[1]);
-
- // Now check that if we add the preimage to ChannelMonitor it broadcasts our HTLC-Success..
- {
- let mut monitors = nodes[2].chan_monitor.simple_monitor.monitors.lock().unwrap();
- monitors.get_mut(&OutPoint::new(Sha256dHash::from(&payment_event.commitment_msg.channel_id[..]), 0)).unwrap()
- .provide_payment_preimage(&our_payment_hash, &our_payment_preimage);
- }
- nodes[2].chain_monitor.block_connected_checked(&header, 1, &[&tx], &[1]);
- let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap();
- assert_eq!(node_txn.len(), 1);
- assert_eq!(node_txn[0].input.len(), 1);
- assert_eq!(node_txn[0].input[0].previous_output.txid, tx.txid());
- assert_eq!(node_txn[0].lock_time, 0); // Must be an HTLC-Success
- assert_eq!(node_txn[0].input[0].witness.len(), 5); // Must be an HTLC-Success
-
- check_spends!(node_txn[0], tx);
-}
-
-#[test]
-fn test_unconf_chan() {
- // After creating a chan between nodes, we disconnect all blocks previously seen to force a channel close on nodes[0] side
- let nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
-
- let channel_state = nodes[0].node.channel_state.lock().unwrap();
- assert_eq!(channel_state.by_id.len(), 1);
- assert_eq!(channel_state.short_to_id.len(), 1);
- mem::drop(channel_state);
-
- let mut headers = Vec::new();
- let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
- headers.push(header.clone());
- for _i in 2..100 {
- header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
- headers.push(header.clone());
- }
- while !headers.is_empty() {
- nodes[0].node.block_disconnected(&headers.pop().unwrap());
- }
- check_closed_broadcast!(nodes[0]);
- let channel_state = nodes[0].node.channel_state.lock().unwrap();
- assert_eq!(channel_state.by_id.len(), 0);
- assert_eq!(channel_state.short_to_id.len(), 0);
-}
-
-macro_rules! get_chan_reestablish_msgs {
- ($src_node: expr, $dst_node: expr) => {
- {
- let mut res = Vec::with_capacity(1);
- for msg in $src_node.node.get_and_clear_pending_msg_events() {
- if let MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } = msg {
- assert_eq!(*node_id, $dst_node.node.get_our_node_id());
- res.push(msg.clone());
- } else {
- panic!("Unexpected event")
- }
- }
- res
- }
- }
-}
-
-macro_rules! handle_chan_reestablish_msgs {
- ($src_node: expr, $dst_node: expr) => {
- {
- let msg_events = $src_node.node.get_and_clear_pending_msg_events();
- let mut idx = 0;
- let funding_locked = if let Some(&MessageSendEvent::SendFundingLocked { ref node_id, ref msg }) = msg_events.get(0) {
- idx += 1;
- assert_eq!(*node_id, $dst_node.node.get_our_node_id());
- Some(msg.clone())
- } else {
- None
- };
-
- let mut revoke_and_ack = None;
- let mut commitment_update = None;
- let order = if let Some(ev) = msg_events.get(idx) {
- idx += 1;
- match ev {
- &MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
- assert_eq!(*node_id, $dst_node.node.get_our_node_id());
- revoke_and_ack = Some(msg.clone());
- RAACommitmentOrder::RevokeAndACKFirst
- },
- &MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
- assert_eq!(*node_id, $dst_node.node.get_our_node_id());
- commitment_update = Some(updates.clone());
- RAACommitmentOrder::CommitmentFirst
- },
- _ => panic!("Unexpected event"),
- }
- } else {
- RAACommitmentOrder::CommitmentFirst
- };
-
- if let Some(ev) = msg_events.get(idx) {
- match ev {
- &MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
- assert_eq!(*node_id, $dst_node.node.get_our_node_id());
- assert!(revoke_and_ack.is_none());
- revoke_and_ack = Some(msg.clone());
- },
- &MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
- assert_eq!(*node_id, $dst_node.node.get_our_node_id());
- assert!(commitment_update.is_none());
- commitment_update = Some(updates.clone());
- },
- _ => panic!("Unexpected event"),
- }
- }
-
- (funding_locked, revoke_and_ack, commitment_update, order)
- }
- }
-}
-
-/// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas
-/// for claims/fails they are separated out.
-fn reconnect_nodes(node_a: &Node, node_b: &Node, send_funding_locked: (bool, bool), pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool)) {
- node_a.node.peer_connected(&node_b.node.get_our_node_id());
- let reestablish_1 = get_chan_reestablish_msgs!(node_a, node_b);
- node_b.node.peer_connected(&node_a.node.get_our_node_id());
- let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a);
-
- if send_funding_locked.0 {
- // If a expects a funding_locked, it better not think it has received a revoke_and_ack
- // from b
- for reestablish in reestablish_1.iter() {
- assert_eq!(reestablish.next_remote_commitment_number, 0);
- }
- }
- if send_funding_locked.1 {
- // If b expects a funding_locked, it better not think it has received a revoke_and_ack
- // from a
- for reestablish in reestablish_2.iter() {
- assert_eq!(reestablish.next_remote_commitment_number, 0);
- }
- }
- if send_funding_locked.0 || send_funding_locked.1 {
- // If we expect any funding_locked's, both sides better have set
- // next_local_commitment_number to 1
- for reestablish in reestablish_1.iter() {
- assert_eq!(reestablish.next_local_commitment_number, 1);
- }
- for reestablish in reestablish_2.iter() {
- assert_eq!(reestablish.next_local_commitment_number, 1);
- }
- }
-
- let mut resp_1 = Vec::new();
- for msg in reestablish_1 {
- node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap();
- resp_1.push(handle_chan_reestablish_msgs!(node_b, node_a));
- }
- if pending_cell_htlc_claims.0 != 0 || pending_cell_htlc_fails.0 != 0 {
- check_added_monitors!(node_b, 1);
- } else {
- check_added_monitors!(node_b, 0);
- }
-
- let mut resp_2 = Vec::new();
- for msg in reestablish_2 {
- node_a.node.handle_channel_reestablish(&node_b.node.get_our_node_id(), &msg).unwrap();
- resp_2.push(handle_chan_reestablish_msgs!(node_a, node_b));
- }
- if pending_cell_htlc_claims.1 != 0 || pending_cell_htlc_fails.1 != 0 {
- check_added_monitors!(node_a, 1);
- } else {
- check_added_monitors!(node_a, 0);
- }
-
- // We dont yet support both needing updates, as that would require a different commitment dance:
- assert!((pending_htlc_adds.0 == 0 && pending_htlc_claims.0 == 0 && pending_cell_htlc_claims.0 == 0 && pending_cell_htlc_fails.0 == 0) ||
- (pending_htlc_adds.1 == 0 && pending_htlc_claims.1 == 0 && pending_cell_htlc_claims.1 == 0 && pending_cell_htlc_fails.1 == 0));
-
- for chan_msgs in resp_1.drain(..) {
- if send_funding_locked.0 {
- node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), &chan_msgs.0.unwrap()).unwrap();
- let announcement_event = node_a.node.get_and_clear_pending_msg_events();
- if !announcement_event.is_empty() {
- assert_eq!(announcement_event.len(), 1);
- if let MessageSendEvent::SendAnnouncementSignatures { .. } = announcement_event[0] {
- //TODO: Test announcement_sigs re-sending
- } else { panic!("Unexpected event!"); }
- }
- } else {
- assert!(chan_msgs.0.is_none());
- }
- if pending_raa.0 {
- assert!(chan_msgs.3 == RAACommitmentOrder::RevokeAndACKFirst);
- node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap();
- assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
- check_added_monitors!(node_a, 1);
- } else {
- assert!(chan_msgs.1.is_none());
- }
- if pending_htlc_adds.0 != 0 || pending_htlc_claims.0 != 0 || pending_cell_htlc_claims.0 != 0 || pending_cell_htlc_fails.0 != 0 {
- let commitment_update = chan_msgs.2.unwrap();
- if pending_htlc_adds.0 != -1 { // We use -1 to denote a response commitment_signed
- assert_eq!(commitment_update.update_add_htlcs.len(), pending_htlc_adds.0 as usize);
- } else {
- assert!(commitment_update.update_add_htlcs.is_empty());
- }
- assert_eq!(commitment_update.update_fulfill_htlcs.len(), pending_htlc_claims.0 + pending_cell_htlc_claims.0);
- assert_eq!(commitment_update.update_fail_htlcs.len(), pending_cell_htlc_fails.0);
- assert!(commitment_update.update_fail_malformed_htlcs.is_empty());
- for update_add in commitment_update.update_add_htlcs {
- node_a.node.handle_update_add_htlc(&node_b.node.get_our_node_id(), &update_add).unwrap();
- }
- for update_fulfill in commitment_update.update_fulfill_htlcs {
- node_a.node.handle_update_fulfill_htlc(&node_b.node.get_our_node_id(), &update_fulfill).unwrap();
- }
- for update_fail in commitment_update.update_fail_htlcs {
- node_a.node.handle_update_fail_htlc(&node_b.node.get_our_node_id(), &update_fail).unwrap();
- }
-
- if pending_htlc_adds.0 != -1 { // We use -1 to denote a response commitment_signed
- commitment_signed_dance!(node_a, node_b, commitment_update.commitment_signed, false);
- } else {
- node_a.node.handle_commitment_signed(&node_b.node.get_our_node_id(), &commitment_update.commitment_signed).unwrap();
- check_added_monitors!(node_a, 1);
- let as_revoke_and_ack = get_event_msg!(node_a, MessageSendEvent::SendRevokeAndACK, node_b.node.get_our_node_id());
- // No commitment_signed so get_event_msg's assert(len == 1) passes
- node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &as_revoke_and_ack).unwrap();
- assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
- check_added_monitors!(node_b, 1);
- }
- } else {
- assert!(chan_msgs.2.is_none());
- }
- }
-
- for chan_msgs in resp_2.drain(..) {
- if send_funding_locked.1 {
- node_b.node.handle_funding_locked(&node_a.node.get_our_node_id(), &chan_msgs.0.unwrap()).unwrap();
- let announcement_event = node_b.node.get_and_clear_pending_msg_events();
- if !announcement_event.is_empty() {
- assert_eq!(announcement_event.len(), 1);
- if let MessageSendEvent::SendAnnouncementSignatures { .. } = announcement_event[0] {
- //TODO: Test announcement_sigs re-sending
- } else { panic!("Unexpected event!"); }
- }
- } else {
- assert!(chan_msgs.0.is_none());
- }
- if pending_raa.1 {
- assert!(chan_msgs.3 == RAACommitmentOrder::RevokeAndACKFirst);
- node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap();
- assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
- check_added_monitors!(node_b, 1);
- } else {
- assert!(chan_msgs.1.is_none());
- }
- if pending_htlc_adds.1 != 0 || pending_htlc_claims.1 != 0 || pending_cell_htlc_claims.1 != 0 || pending_cell_htlc_fails.1 != 0 {
- let commitment_update = chan_msgs.2.unwrap();
- if pending_htlc_adds.1 != -1 { // We use -1 to denote a response commitment_signed
- assert_eq!(commitment_update.update_add_htlcs.len(), pending_htlc_adds.1 as usize);
- }
- assert_eq!(commitment_update.update_fulfill_htlcs.len(), pending_htlc_claims.0 + pending_cell_htlc_claims.0);
- assert_eq!(commitment_update.update_fail_htlcs.len(), pending_cell_htlc_fails.0);
- assert!(commitment_update.update_fail_malformed_htlcs.is_empty());
- for update_add in commitment_update.update_add_htlcs {
- node_b.node.handle_update_add_htlc(&node_a.node.get_our_node_id(), &update_add).unwrap();
- }
- for update_fulfill in commitment_update.update_fulfill_htlcs {
- node_b.node.handle_update_fulfill_htlc(&node_a.node.get_our_node_id(), &update_fulfill).unwrap();
- }
- for update_fail in commitment_update.update_fail_htlcs {
- node_b.node.handle_update_fail_htlc(&node_a.node.get_our_node_id(), &update_fail).unwrap();
- }
-
- if pending_htlc_adds.1 != -1 { // We use -1 to denote a response commitment_signed
- commitment_signed_dance!(node_b, node_a, commitment_update.commitment_signed, false);
- } else {
- node_b.node.handle_commitment_signed(&node_a.node.get_our_node_id(), &commitment_update.commitment_signed).unwrap();
- check_added_monitors!(node_b, 1);
- let bs_revoke_and_ack = get_event_msg!(node_b, MessageSendEvent::SendRevokeAndACK, node_a.node.get_our_node_id());
- // No commitment_signed so get_event_msg's assert(len == 1) passes
- node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &bs_revoke_and_ack).unwrap();
- assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
- check_added_monitors!(node_a, 1);
- }
- } else {
- assert!(chan_msgs.2.is_none());
- }
- }
-}
-
-#[test]
-fn test_simple_peer_disconnect() {
- // Test that we can reconnect when there are no lost messages
- let nodes = create_network(3);
- create_announced_chan_between_nodes(&nodes, 0, 1);
- create_announced_chan_between_nodes(&nodes, 1, 2);
-
- 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);
- reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
-
- let payment_preimage_1 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0;
- let payment_hash_2 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1;
- fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_hash_2);
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_1);
-
- 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);
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
-
- let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0;
- let payment_preimage_4 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0;
- let payment_hash_5 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1;
- let payment_hash_6 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1;
-
- 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);
-
- claim_payment_along_route(&nodes[0], &vec!(&nodes[1], &nodes[2]), true, payment_preimage_3);
- fail_payment_along_route(&nodes[0], &[&nodes[1], &nodes[2]], true, payment_hash_5);
-
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (1, 0), (1, 0), (false, false));
- {
- let events = nodes[0].node.get_and_clear_pending_events();
- assert_eq!(events.len(), 2);
- match events[0] {
- Event::PaymentSent { payment_preimage } => {
- assert_eq!(payment_preimage, payment_preimage_3);
- },
- _ => panic!("Unexpected event"),
- }
- match events[1] {
- Event::PaymentFailed { payment_hash, rejected_by_dest, .. } => {
- assert_eq!(payment_hash, payment_hash_5);
- assert!(rejected_by_dest);
- },
- _ => panic!("Unexpected event"),
- }
- }
-
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_4);
- fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_hash_6);
-}
-
-fn do_test_drop_messages_peer_disconnect(messages_delivered: u8) {
- // Test that we can reconnect when in-flight HTLC updates get dropped
- let mut nodes = create_network(2);
- if messages_delivered == 0 {
- create_chan_between_nodes_with_value_a(&nodes[0], &nodes[1], 100000, 10001);
- // nodes[1] doesn't receive the funding_locked message (it'll be re-sent on reconnect)
- } else {
- create_announced_chan_between_nodes(&nodes, 0, 1);
- }
-
- let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), Some(&nodes[0].node.list_usable_channels()), &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
- 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();
- 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))
- };
- assert_eq!(nodes[1].node.get_our_node_id(), payment_event.node_id);
-
- if messages_delivered < 2 {
- // Drop the payment_event messages, and let them get re-generated in reconnect_nodes!
- } else {
- nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]).unwrap();
- if messages_delivered >= 3 {
- nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg).unwrap();
- check_added_monitors!(nodes[1], 1);
- let (bs_revoke_and_ack, bs_commitment_signed) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id());
-
- if messages_delivered >= 4 {
- nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap();
- assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
- check_added_monitors!(nodes[0], 1);
-
- if messages_delivered >= 5 {
- nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_commitment_signed).unwrap();
- let as_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);
-
- if messages_delivered >= 6 {
- nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap();
- assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
- check_added_monitors!(nodes[1], 1);
- }
- }
- }
- }
- }
-
- 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);
- if messages_delivered < 3 {
- // Even if the funding_locked messages get exchanged, as long as nothing further was
- // received on either side, both sides will need to resend them.
- reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 1), (0, 0), (0, 0), (0, 0), (false, false));
- } else if messages_delivered == 3 {
- // nodes[0] still wants its RAA + commitment_signed
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (-1, 0), (0, 0), (0, 0), (0, 0), (true, false));
- } else if messages_delivered == 4 {
- // nodes[0] still wants its commitment_signed
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (-1, 0), (0, 0), (0, 0), (0, 0), (false, false));
- } else if messages_delivered == 5 {
- // nodes[1] still wants its final RAA
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, true));
- } else if messages_delivered == 6 {
- // Everything was delivered...
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
- }
-
- let events_1 = nodes[1].node.get_and_clear_pending_events();
- assert_eq!(events_1.len(), 1);
- match events_1[0] {
- Event::PendingHTLCsForwardable { .. } => { },
- _ => panic!("Unexpected event"),
- };
-
- 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);
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
-
- nodes[1].node.channel_state.lock().unwrap().next_forward = Instant::now();
- nodes[1].node.process_pending_htlc_forwards();
-
- 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 } => {
- assert_eq!(payment_hash_1, *payment_hash);
- assert_eq!(amt, 1000000);
- },
- _ => panic!("Unexpected event"),
- }
-
- nodes[1].node.claim_funds(payment_preimage_1);
- check_added_monitors!(nodes[1], 1);
-
- let events_3 = nodes[1].node.get_and_clear_pending_msg_events();
- assert_eq!(events_3.len(), 1);
- let (update_fulfill_htlc, commitment_signed) = match events_3[0] {
- MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
- assert_eq!(*node_id, nodes[0].node.get_our_node_id());
- assert!(updates.update_add_htlcs.is_empty());
- assert!(updates.update_fail_htlcs.is_empty());
- assert_eq!(updates.update_fulfill_htlcs.len(), 1);
- assert!(updates.update_fail_malformed_htlcs.is_empty());
- assert!(updates.update_fee.is_none());
- (updates.update_fulfill_htlcs[0].clone(), updates.commitment_signed.clone())
- },
- _ => panic!("Unexpected event"),
- };
-
- if messages_delivered >= 1 {
- nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &update_fulfill_htlc).unwrap();
-
- let events_4 = nodes[0].node.get_and_clear_pending_events();
- assert_eq!(events_4.len(), 1);
- match events_4[0] {
- Event::PaymentSent { ref payment_preimage } => {
- assert_eq!(payment_preimage_1, *payment_preimage);
- },
- _ => panic!("Unexpected event"),
- }
-
- if messages_delivered >= 2 {
- nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed).unwrap();
- check_added_monitors!(nodes[0], 1);
- let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
-
- if messages_delivered >= 3 {
- nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap();
- assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
- check_added_monitors!(nodes[1], 1);
-
- if messages_delivered >= 4 {
- nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_signed).unwrap();
- let bs_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
- // No commitment_signed so get_event_msg's assert(len == 1) passes
- check_added_monitors!(nodes[1], 1);
-
- if messages_delivered >= 5 {
- nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap();
- assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
- check_added_monitors!(nodes[0], 1);
- }
- }
- }
- }
- }
-
- 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);
- if messages_delivered < 2 {
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (1, 0), (0, 0), (0, 0), (false, false));
- //TODO: Deduplicate PaymentSent events, then enable this if:
- //if messages_delivered < 1 {
- let events_4 = nodes[0].node.get_and_clear_pending_events();
- assert_eq!(events_4.len(), 1);
- match events_4[0] {
- Event::PaymentSent { ref payment_preimage } => {
- assert_eq!(payment_preimage_1, *payment_preimage);
- },
- _ => panic!("Unexpected event"),
- }
- //}
- } else if messages_delivered == 2 {
- // nodes[0] still wants its RAA + commitment_signed
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, -1), (0, 0), (0, 0), (0, 0), (false, true));
- } else if messages_delivered == 3 {
- // nodes[0] still wants its commitment_signed
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, -1), (0, 0), (0, 0), (0, 0), (false, false));
- } else if messages_delivered == 4 {
- // nodes[1] still wants its final RAA
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (true, false));
- } else if messages_delivered == 5 {
- // Everything was delivered...
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
- }
-
- 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);
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
-
- // Channel should still work fine...
- let payment_preimage_2 = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000).0;
- claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
-}
-
-#[test]
-fn test_drop_messages_peer_disconnect_a() {
- do_test_drop_messages_peer_disconnect(0);
- do_test_drop_messages_peer_disconnect(1);
- do_test_drop_messages_peer_disconnect(2);
- do_test_drop_messages_peer_disconnect(3);
-}
-
-#[test]
-fn test_drop_messages_peer_disconnect_b() {
- do_test_drop_messages_peer_disconnect(4);
- do_test_drop_messages_peer_disconnect(5);
- do_test_drop_messages_peer_disconnect(6);
-}
-
-#[test]
-fn test_funding_peer_disconnect() {
- // Test that we can lock in our funding tx while disconnected
- let nodes = create_network(2);
- let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001);
-
- 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);
-
- confirm_transaction(&nodes[0].chain_monitor, &tx, tx.version);
- let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
- assert_eq!(events_1.len(), 1);
- match events_1[0] {
- MessageSendEvent::SendFundingLocked { ref node_id, msg: _ } => {
- assert_eq!(*node_id, nodes[1].node.get_our_node_id());
- },
- _ => panic!("Unexpected event"),
- }
-
- reconnect_nodes(&nodes[0], &nodes[1], (false, true), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
-
- 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);
-
- confirm_transaction(&nodes[1].chain_monitor, &tx, tx.version);
- let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
- assert_eq!(events_2.len(), 2);
- match events_2[0] {
- MessageSendEvent::SendFundingLocked { ref node_id, msg: _ } => {
- assert_eq!(*node_id, nodes[0].node.get_our_node_id());
- },
- _ => panic!("Unexpected event"),
- }
- match events_2[1] {
- MessageSendEvent::SendAnnouncementSignatures { ref node_id, msg: _ } => {
- assert_eq!(*node_id, nodes[0].node.get_our_node_id());
- },
- _ => panic!("Unexpected event"),
- }
-
- reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
-
- // TODO: We shouldn't need to manually pass list_usable_chanels here once we support
- // rebroadcasting announcement_signatures upon reconnect.
-
- let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), Some(&nodes[0].node.list_usable_channels()), &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
- let (payment_preimage, _) = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000);
- claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
-}
-
-#[test]
-fn test_drop_messages_peer_disconnect_dual_htlc() {
- // Test that we can handle reconnecting when both sides of a channel have pending
- // commitment_updates when we disconnect.
- let mut nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
-
- let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
-
- // Now try to send a second payment which will fail to send
- 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();
- check_added_monitors!(nodes[0], 1);
-
- let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
- assert_eq!(events_1.len(), 1);
- match events_1[0] {
- MessageSendEvent::UpdateHTLCs { .. } => {},
- _ => panic!("Unexpected event"),
- }
-
- assert!(nodes[1].node.claim_funds(payment_preimage_1));
- check_added_monitors!(nodes[1], 1);
-
- let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
- assert_eq!(events_2.len(), 1);
- match events_2[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_eq!(*node_id, nodes[0].node.get_our_node_id());
- 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());
-
- nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &update_fulfill_htlcs[0]).unwrap();
- let events_3 = nodes[0].node.get_and_clear_pending_events();
- assert_eq!(events_3.len(), 1);
- match events_3[0] {
- Event::PaymentSent { ref payment_preimage } => {
- assert_eq!(*payment_preimage, payment_preimage_1);
- },
- _ => panic!("Unexpected event"),
- }
-
- nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), commitment_signed).unwrap();
- let _ = 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);
- },
- _ => panic!("Unexpected event"),
- }
-
- 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 reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
- assert_eq!(reestablish_1.len(), 1);
- nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
- let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
- assert_eq!(reestablish_2.len(), 1);
-
- nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap();
- let as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
- nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap();
- let bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
-
- assert!(as_resp.0.is_none());
- assert!(bs_resp.0.is_none());
-
- assert!(bs_resp.1.is_none());
- assert!(bs_resp.2.is_none());
-
- assert!(as_resp.3 == RAACommitmentOrder::CommitmentFirst);
-
- assert_eq!(as_resp.2.as_ref().unwrap().update_add_htlcs.len(), 1);
- assert!(as_resp.2.as_ref().unwrap().update_fulfill_htlcs.is_empty());
- assert!(as_resp.2.as_ref().unwrap().update_fail_htlcs.is_empty());
- assert!(as_resp.2.as_ref().unwrap().update_fail_malformed_htlcs.is_empty());
- assert!(as_resp.2.as_ref().unwrap().update_fee.is_none());
- nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &as_resp.2.as_ref().unwrap().update_add_htlcs[0]).unwrap();
- nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_resp.2.as_ref().unwrap().commitment_signed).unwrap();
- let bs_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
- // No commitment_signed so get_event_msg's assert(len == 1) passes
- check_added_monitors!(nodes[1], 1);
-
- nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), as_resp.1.as_ref().unwrap()).unwrap();
- let bs_second_commitment_signed = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
- assert!(bs_second_commitment_signed.update_add_htlcs.is_empty());
- assert!(bs_second_commitment_signed.update_fulfill_htlcs.is_empty());
- assert!(bs_second_commitment_signed.update_fail_htlcs.is_empty());
- assert!(bs_second_commitment_signed.update_fail_malformed_htlcs.is_empty());
- assert!(bs_second_commitment_signed.update_fee.is_none());
- check_added_monitors!(nodes[1], 1);
-
- nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap();
- let as_commitment_signed = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
- assert!(as_commitment_signed.update_add_htlcs.is_empty());
- assert!(as_commitment_signed.update_fulfill_htlcs.is_empty());
- assert!(as_commitment_signed.update_fail_htlcs.is_empty());
- assert!(as_commitment_signed.update_fail_malformed_htlcs.is_empty());
- assert!(as_commitment_signed.update_fee.is_none());
- check_added_monitors!(nodes[0], 1);
-
- nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment_signed.commitment_signed).unwrap();
- let as_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_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_signed.commitment_signed).unwrap();
- let bs_second_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
- // No commitment_signed so get_event_msg's assert(len == 1) passes
- check_added_monitors!(nodes[1], 1);
-
- nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_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 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: _ } => {
- assert_eq!(payment_hash_2, *payment_hash);