- 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]);
-
- let events_4 = nodes[1].node.get_and_clear_pending_events();
- // Note no UpdateHTLCs event here from nodes[1] to nodes[0]!
- assert_eq!(events_4.len(), 1);
- match events_4[0] {
- Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => {
- assert_eq!(flags & 0b10, 0b10);
- },
- _ => panic!("Unexpected event"),
- }
-
- // 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
- let mut funding_tx_map = HashMap::new();
- funding_tx_map.insert(tx.txid(), tx);
- node_txn[0].verify(&funding_tx_map).unwrap();
- }
-
- #[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());
- }
- {
- let events = nodes[0].node.get_and_clear_pending_events();
- assert_eq!(events.len(), 1);
- match events[0] {
- Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => {
- assert_eq!(flags & 0b10, 0b10);
- },
- _ => panic!("Unexpected event"),
- }
- }
- 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);
- }
-
- fn reconnect_nodes(node_a: &Node, node_b: &Node, pre_all_htlcs: bool, pending_htlc_claims: (usize, usize), pending_htlc_fails: (usize, usize)) {
- let reestablish_1 = node_a.node.peer_connected(&node_b.node.get_our_node_id());
- let reestablish_2 = node_b.node.peer_connected(&node_a.node.get_our_node_id());
-
- let mut resp_1 = Vec::new();
- for msg in reestablish_1 {
- resp_1.push(node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap());
- }
- if pending_htlc_claims.0 != 0 || pending_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 {
- resp_2.push(node_a.node.handle_channel_reestablish(&node_b.node.get_our_node_id(), &msg).unwrap());
- }
- if pending_htlc_claims.1 != 0 || pending_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_claims.0 == 0 && pending_htlc_fails.0 == 0) || (pending_htlc_claims.1 == 0 && pending_htlc_fails.1 == 0));
-
- for chan_msgs in resp_1.drain(..) {
- if pre_all_htlcs {
- let _announcement_sigs_opt = node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), &chan_msgs.0.unwrap()).unwrap();
- //TODO: Test announcement_sigs re-sending when we've implemented it
- } else {
- assert!(chan_msgs.0.is_none());
- }
- assert!(chan_msgs.1.is_none());
- if pending_htlc_claims.0 != 0 || pending_htlc_fails.0 != 0 {
- let commitment_update = chan_msgs.2.unwrap();
- assert!(commitment_update.update_add_htlcs.is_empty()); // We can't relay while disconnected
- assert_eq!(commitment_update.update_fulfill_htlcs.len(), pending_htlc_claims.0);
- assert_eq!(commitment_update.update_fail_htlcs.len(), pending_htlc_fails.0);
- assert!(commitment_update.update_fail_malformed_htlcs.is_empty());
- 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();
- }
-
- commitment_signed_dance!(node_a, node_b, commitment_update.commitment_signed, false);
- } else {
- assert!(chan_msgs.2.is_none());
- }
- }
-
- for chan_msgs in resp_2.drain(..) {
- if pre_all_htlcs {
- let _announcement_sigs_opt = node_b.node.handle_funding_locked(&node_a.node.get_our_node_id(), &chan_msgs.0.unwrap()).unwrap();
- //TODO: Test announcement_sigs re-sending when we've implemented it
- } else {
- assert!(chan_msgs.0.is_none());
- }
- assert!(chan_msgs.1.is_none());
- if pending_htlc_claims.1 != 0 || pending_htlc_fails.1 != 0 {
- let commitment_update = chan_msgs.2.unwrap();
- assert!(commitment_update.update_add_htlcs.is_empty()); // We can't relay while disconnected
- assert_eq!(commitment_update.update_fulfill_htlcs.len(), pending_htlc_claims.0);
- assert_eq!(commitment_update.update_fail_htlcs.len(), pending_htlc_fails.0);
- assert!(commitment_update.update_fail_malformed_htlcs.is_empty());
- 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();
- }
-
- commitment_signed_dance!(node_b, node_a, commitment_update.commitment_signed, false);
- } 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, (0, 0), (0, 0));
-
- 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, (0, 0), (0, 0));
-
- 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, (1, 0), (1, 0));
- {
- 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 } => {
- assert_eq!(payment_hash, payment_hash_5);
- },
- _ => 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);
- }
-
- #[test]
- fn test_invalid_channel_announcement() {
- //Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs
- let secp_ctx = Secp256k1::new();
- let nodes = create_network(2);
-
- let chan_announcement = create_chan_between_nodes(&nodes[0], &nodes[1]);
-
- let a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
- let b_channel_lock = nodes[1].node.channel_state.lock().unwrap();
- let as_chan = a_channel_lock.by_id.get(&chan_announcement.3).unwrap();
- let bs_chan = b_channel_lock.by_id.get(&chan_announcement.3).unwrap();
-
- let _ = nodes[0].router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id : as_chan.get_short_channel_id().unwrap() } );
-
- let as_bitcoin_key = PublicKey::from_secret_key(&secp_ctx, &as_chan.get_local_keys().funding_key);
- let bs_bitcoin_key = PublicKey::from_secret_key(&secp_ctx, &bs_chan.get_local_keys().funding_key);
-
- let as_network_key = nodes[0].node.get_our_node_id();
- let bs_network_key = nodes[1].node.get_our_node_id();
-
- let were_node_one = as_bitcoin_key.serialize()[..] < bs_bitcoin_key.serialize()[..];
-
- let mut chan_announcement;
-
- macro_rules! dummy_unsigned_msg {
- () => {
- msgs::UnsignedChannelAnnouncement {
- features: msgs::GlobalFeatures::new(),
- chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
- short_channel_id: as_chan.get_short_channel_id().unwrap(),
- node_id_1: if were_node_one { as_network_key } else { bs_network_key },
- node_id_2: if were_node_one { bs_network_key } else { as_network_key },
- bitcoin_key_1: if were_node_one { as_bitcoin_key } else { bs_bitcoin_key },
- bitcoin_key_2: if were_node_one { bs_bitcoin_key } else { as_bitcoin_key },
- excess_data: Vec::new(),
- };
- }
- }
-
- macro_rules! sign_msg {
- ($unsigned_msg: expr) => {
- let msghash = Message::from_slice(&Sha256dHash::from_data(&$unsigned_msg.encode()[..])[..]).unwrap();
- let as_bitcoin_sig = secp_ctx.sign(&msghash, &as_chan.get_local_keys().funding_key);
- let bs_bitcoin_sig = secp_ctx.sign(&msghash, &bs_chan.get_local_keys().funding_key);
- let as_node_sig = secp_ctx.sign(&msghash, &nodes[0].node.our_network_key);
- let bs_node_sig = secp_ctx.sign(&msghash, &nodes[1].node.our_network_key);
- chan_announcement = msgs::ChannelAnnouncement {
- node_signature_1 : if were_node_one { as_node_sig } else { bs_node_sig},
- node_signature_2 : if were_node_one { bs_node_sig } else { as_node_sig},
- bitcoin_signature_1: if were_node_one { as_bitcoin_sig } else { bs_bitcoin_sig },
- bitcoin_signature_2 : if were_node_one { bs_bitcoin_sig } else { as_bitcoin_sig },
- contents: $unsigned_msg
- }
- }