+ node.router.handle_channel_update(&as_update).unwrap();
+ node.router.handle_channel_update(&bs_update).unwrap();
+ }
+ }
+
+ #[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_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ Event::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);
+
+ // One pending HTLC to time out:
+ let payment_preimage_2 = route_payment(&nodes[3], &vec!(&nodes[4])[..], 3000000).0;
+
+ {
+ 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, 1, &Vec::new()[..], &[0; 0]);
+ for i in 2..TEST_FINAL_CLTV - 3 {
+ 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, 1, &Vec::new()[..], &[0; 0]);
+ for i in 2..TEST_FINAL_CLTV - 3 {
+ 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);
+
+ // 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();
+ // 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(), 1);
+
+ let mut funding_tx_map = HashMap::new();
+ funding_tx_map.insert(revoked_local_txn[0].txid(), revoked_local_txn[0].clone());
+ node_txn[0].verify(&funding_tx_map).unwrap();
+ node_txn.swap_remove(0);
+ }
+ test_txn_broadcast(&nodes[1], &chan_5, None, HTLCType::NONE);
+
+ nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
+ let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT);
+ header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[1].clone()] }, 1);
+ test_revoked_htlc_claim_txn_broadcast(&nodes[1], node_txn[1].clone());
+ }
+ 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(), 0);
+ }
+
+ #[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);
+ {
+ 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 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]);
+
+ {
+ let events = nodes[1].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"),
+ }
+ }
+
+ // 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_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);
+
+ 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[1].node.channel_state.lock().unwrap().next_forward = Instant::now();
+ nodes[1].node.process_pending_htlc_forwards();
+
+ let mut events_2 = nodes[1].node.get_and_clear_pending_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);
+
+ // 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);
+ let events_3 = nodes[2].node.get_and_clear_pending_events();
+ assert_eq!(events_3.len(), 1);
+ match events_3[0] {
+ Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => {
+ assert_eq!(flags & 0b10, 0b10);
+ },
+ _ => panic!("Unexpected event"),
+ }
+
+ 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]);
+
+ 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);