+
+ #[test]
+ fn test_id_to_peer_coverage() {
+ // Test that the `ChannelManager:id_to_peer` contains channels which have been assigned
+ // a `channel_id` (i.e. have had the funding tx created), and that they are removed once
+ // the channel is successfully closed.
+ let chanmon_cfgs = create_chanmon_cfgs(2);
+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+ let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+ nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None).unwrap();
+ let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel);
+ let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+ nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &accept_channel);
+
+ let (temporary_channel_id, tx, _funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42);
+ let channel_id = &tx.txid().into_inner();
+ {
+ // Ensure that the `id_to_peer` map is empty until either party has received the
+ // funding transaction, and have the real `channel_id`.
+ assert_eq!(nodes[0].node.id_to_peer.lock().unwrap().len(), 0);
+ assert_eq!(nodes[1].node.id_to_peer.lock().unwrap().len(), 0);
+ }
+
+ nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap();
+ {
+ // Assert that `nodes[0]`'s `id_to_peer` map is populated with the channel as soon as
+ // as it has the funding transaction.
+ let nodes_0_lock = nodes[0].node.id_to_peer.lock().unwrap();
+ assert_eq!(nodes_0_lock.len(), 1);
+ assert!(nodes_0_lock.contains_key(channel_id));
+
+ assert_eq!(nodes[1].node.id_to_peer.lock().unwrap().len(), 0);
+ }
+
+ let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
+
+ nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
+ {
+ let nodes_0_lock = nodes[0].node.id_to_peer.lock().unwrap();
+ assert_eq!(nodes_0_lock.len(), 1);
+ assert!(nodes_0_lock.contains_key(channel_id));
+
+ // Assert that `nodes[1]`'s `id_to_peer` map is populated with the channel as soon as
+ // as it has the funding transaction.
+ let nodes_1_lock = nodes[1].node.id_to_peer.lock().unwrap();
+ assert_eq!(nodes_1_lock.len(), 1);
+ assert!(nodes_1_lock.contains_key(channel_id));
+ }
+ check_added_monitors!(nodes[1], 1);
+ let funding_signed = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+ nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed);
+ check_added_monitors!(nodes[0], 1);
+ let (channel_ready, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
+ let (announcement, nodes_0_update, nodes_1_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready);
+ update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &nodes_0_update, &nodes_1_update);
+
+ nodes[0].node.close_channel(channel_id, &nodes[1].node.get_our_node_id()).unwrap();
+ nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()));
+ let nodes_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
+ nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &channelmanager::provided_init_features(), &nodes_1_shutdown);
+
+ let closing_signed_node_0 = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
+ nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &closing_signed_node_0);
+ {
+ // Assert that the channel is kept in the `id_to_peer` map for both nodes until the
+ // channel can be fully closed by both parties (i.e. no outstanding htlcs exists, the
+ // fee for the closing transaction has been negotiated and the parties has the other
+ // party's signature for the fee negotiated closing transaction.)
+ let nodes_0_lock = nodes[0].node.id_to_peer.lock().unwrap();
+ assert_eq!(nodes_0_lock.len(), 1);
+ assert!(nodes_0_lock.contains_key(channel_id));
+
+ // At this stage, `nodes[1]` has proposed a fee for the closing transaction in the
+ // `handle_closing_signed` call above. As `nodes[1]` has not yet received the signature
+ // from `nodes[0]` for the closing transaction with the proposed fee, the channel is
+ // kept in the `nodes[1]`'s `id_to_peer` map.
+ let nodes_1_lock = nodes[1].node.id_to_peer.lock().unwrap();
+ assert_eq!(nodes_1_lock.len(), 1);
+ assert!(nodes_1_lock.contains_key(channel_id));
+ }
+
+ nodes[0].node.handle_closing_signed(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendClosingSigned, nodes[0].node.get_our_node_id()));
+ {
+ // `nodes[0]` accepts `nodes[1]`'s proposed fee for the closing transaction, and
+ // therefore has all it needs to fully close the channel (both signatures for the
+ // closing transaction).
+ // Assert that the channel is removed from `nodes[0]`'s `id_to_peer` map as it can be
+ // fully closed by `nodes[0]`.
+ assert_eq!(nodes[0].node.id_to_peer.lock().unwrap().len(), 0);
+
+ // Assert that the channel is still in `nodes[1]`'s `id_to_peer` map, as `nodes[1]`
+ // doesn't have `nodes[0]`'s signature for the closing transaction yet.
+ let nodes_1_lock = nodes[1].node.id_to_peer.lock().unwrap();
+ assert_eq!(nodes_1_lock.len(), 1);
+ assert!(nodes_1_lock.contains_key(channel_id));
+ }
+
+ let (_nodes_0_update, closing_signed_node_0) = get_closing_signed_broadcast!(nodes[0].node, nodes[1].node.get_our_node_id());
+
+ nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &closing_signed_node_0.unwrap());
+ {
+ // Assert that the channel has now been removed from both parties `id_to_peer` map once
+ // they both have everything required to fully close the channel.
+ assert_eq!(nodes[1].node.id_to_peer.lock().unwrap().len(), 0);
+ }
+ let (_nodes_1_update, _none) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
+
+ check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure);
+ check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure);
+ }
+
+ fn check_unkown_peer_msg_event<'a, 'b: 'a, 'c: 'b>(node: &Node<'a, 'b, 'c>, closing_node_id: PublicKey, closed_channel_id: [u8; 32]){
+ let close_msg_ev = node.node.get_and_clear_pending_msg_events();
+ let expected_error_str = format!("Can't find a peer matching the passed counterparty node_id {}", closing_node_id);
+ match close_msg_ev[0] {
+ MessageSendEvent::HandleError {
+ ref node_id, action: msgs::ErrorAction::SendErrorMessage {
+ msg: msgs::ErrorMessage { ref channel_id, ref data }
+ }
+ } => {
+ assert_eq!(*node_id, closing_node_id);
+ assert_eq!(*data, expected_error_str);
+ assert_eq!(*channel_id, closed_channel_id);
+ }
+ _ => panic!("Unexpected event"),
+ }
+ }
+
+ fn check_not_connected_to_peer_error<T>(res_err: Result<T, APIError>, expected_public_key: PublicKey) {
+ let expected_message = format!("Not connected to node: {}", expected_public_key);
+ check_api_misuse_error_message(expected_message, res_err)
+ }
+
+ fn check_unkown_peer_error<T>(res_err: Result<T, APIError>, expected_public_key: PublicKey) {
+ let expected_message = format!("Can't find a peer matching the passed counterparty node_id {}", expected_public_key);
+ check_api_misuse_error_message(expected_message, res_err)
+ }
+
+ fn check_api_misuse_error_message<T>(expected_err_message: String, res_err: Result<T, APIError>) {
+ match res_err {
+ Err(APIError::APIMisuseError { err }) => {
+ assert_eq!(err, expected_err_message);
+ },
+ Ok(_) => panic!("Unexpected Ok"),
+ Err(_) => panic!("Unexpected Error"),
+ }
+ }
+
+ #[test]
+ fn test_api_calls_with_unkown_counterparty_node() {
+ // Tests that our API functions and message handlers that expects a `counterparty_node_id`
+ // as input, behaves as expected if the `counterparty_node_id` is an unkown peer in the
+ // `ChannelManager::per_peer_state` map.
+ let chanmon_cfg = create_chanmon_cfgs(2);
+ let node_cfg = create_node_cfgs(2, &chanmon_cfg);
+ let node_chanmgr = create_node_chanmgrs(2, &node_cfg, &[None, None]);
+ let nodes = create_network(2, &node_cfg, &node_chanmgr);
+
+ // Boilerplate code to produce `open_channel` and `accept_channel` msgs more densly than
+ // creating dummy ones.
+ nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None).unwrap();
+ let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &open_channel_msg);
+ let accept_channel_msg = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+
+ // Dummy values
+ let channel_id = [4; 32];
+ let signature = Signature::from(unsafe { FFISignature::new() });
+ let unkown_public_key = PublicKey::from_secret_key(&Secp256k1::signing_only(), &SecretKey::from_slice(&[42; 32]).unwrap());
+ let intercept_id = InterceptId([0; 32]);
+
+ // Dummy msgs
+ let funding_created_msg = msgs::FundingCreated {
+ temporary_channel_id: open_channel_msg.temporary_channel_id,
+ funding_txid: Txid::from_hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(),
+ funding_output_index: 0,
+ signature: signature,
+ };
+
+ let funding_signed_msg = msgs::FundingSigned {
+ channel_id: channel_id,
+ signature: signature,
+ };
+
+ let channel_ready_msg = msgs::ChannelReady {
+ channel_id: channel_id,
+ next_per_commitment_point: unkown_public_key,
+ short_channel_id_alias: None,
+ };
+
+ let announcement_signatures_msg = msgs::AnnouncementSignatures {
+ channel_id: channel_id,
+ short_channel_id: 0,
+ node_signature: signature,
+ bitcoin_signature: signature,
+ };
+
+ let channel_reestablish_msg = msgs::ChannelReestablish {
+ channel_id: channel_id,
+ next_local_commitment_number: 0,
+ next_remote_commitment_number: 0,
+ data_loss_protect: OptionalField::Absent,
+ };
+
+ let closing_signed_msg = msgs::ClosingSigned {
+ channel_id: channel_id,
+ fee_satoshis: 1000,
+ signature: signature,
+ fee_range: None,
+ };
+
+ let shutdown_msg = msgs::Shutdown {
+ channel_id: channel_id,
+ scriptpubkey: Script::new(),
+ };
+
+ let onion_routing_packet = msgs::OnionPacket {
+ version: 255,
+ public_key: Ok(unkown_public_key),
+ hop_data: [1; 20*65],
+ hmac: [2; 32]
+ };
+
+ let update_add_htlc_msg = msgs::UpdateAddHTLC {
+ channel_id: channel_id,
+ htlc_id: 0,
+ amount_msat: 1000000,
+ payment_hash: PaymentHash([1; 32]),
+ cltv_expiry: 821716,
+ onion_routing_packet
+ };
+
+ let commitment_signed_msg = msgs::CommitmentSigned {
+ channel_id: channel_id,
+ signature: signature,
+ htlc_signatures: Vec::new(),
+ };
+
+ let update_fee_msg = msgs::UpdateFee {
+ channel_id: channel_id,
+ feerate_per_kw: 1000,
+ };
+
+ let malformed_update_msg = msgs::UpdateFailMalformedHTLC{
+ channel_id: channel_id,
+ htlc_id: 0,
+ sha256_of_onion: [1; 32],
+ failure_code: 0x8000,
+ };
+
+ let fulfill_update_msg = msgs::UpdateFulfillHTLC{
+ channel_id: channel_id,
+ htlc_id: 0,
+ payment_preimage: PaymentPreimage([1; 32]),
+ };
+
+ let fail_update_msg = msgs::UpdateFailHTLC{
+ channel_id: channel_id,
+ htlc_id: 0,
+ reason: msgs::OnionErrorPacket { data: Vec::new()},
+ };
+
+ let revoke_and_ack_msg = msgs::RevokeAndACK {
+ channel_id: channel_id,
+ per_commitment_secret: [1; 32],
+ next_per_commitment_point: unkown_public_key,
+ };
+
+ // Test the API functions and message handlers.
+ check_not_connected_to_peer_error(nodes[0].node.create_channel(unkown_public_key, 1_000_000, 500_000_000, 42, None), unkown_public_key);
+
+ nodes[1].node.handle_open_channel(&unkown_public_key, channelmanager::provided_init_features(), &open_channel_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, open_channel_msg.temporary_channel_id);
+
+ nodes[0].node.handle_accept_channel(&unkown_public_key, channelmanager::provided_init_features(), &accept_channel_msg);
+ check_unkown_peer_msg_event(&nodes[0], unkown_public_key, open_channel_msg.temporary_channel_id);
+
+ check_unkown_peer_error(nodes[0].node.accept_inbound_channel(&open_channel_msg.temporary_channel_id, &unkown_public_key, 42), unkown_public_key);
+ nodes[1].node.handle_funding_created(&unkown_public_key, &funding_created_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, open_channel_msg.temporary_channel_id);
+
+ nodes[0].node.handle_funding_signed(&unkown_public_key, &funding_signed_msg);
+ check_unkown_peer_msg_event(&nodes[0], unkown_public_key, channel_id);
+
+ nodes[0].node.handle_channel_ready(&unkown_public_key, &channel_ready_msg);
+ check_unkown_peer_msg_event(&nodes[0], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_announcement_signatures(&unkown_public_key, &announcement_signatures_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+
+ check_unkown_peer_error(nodes[0].node.close_channel(&channel_id, &unkown_public_key), unkown_public_key);
+
+ check_unkown_peer_error(nodes[0].node.force_close_broadcasting_latest_txn(&channel_id, &unkown_public_key), unkown_public_key);
+
+ check_unkown_peer_error(nodes[0].node.force_close_without_broadcasting_txn(&channel_id, &unkown_public_key), unkown_public_key);
+
+ check_unkown_peer_error(nodes[0].node.forward_intercepted_htlc(intercept_id, &channel_id, unkown_public_key, 1_000_000), unkown_public_key);
+
+ check_unkown_peer_error(nodes[0].node.update_channel_config(&unkown_public_key, &[channel_id], &ChannelConfig::default()), unkown_public_key);
+
+ nodes[0].node.handle_shutdown(&unkown_public_key, &channelmanager::provided_init_features(), &shutdown_msg);
+ check_unkown_peer_msg_event(&nodes[0], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_closing_signed(&unkown_public_key, &closing_signed_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+
+ nodes[0].node.handle_channel_reestablish(&unkown_public_key, &channel_reestablish_msg);
+ check_unkown_peer_msg_event(&nodes[0], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_update_add_htlc(&unkown_public_key, &update_add_htlc_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_commitment_signed(&unkown_public_key, &commitment_signed_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_update_fail_malformed_htlc(&unkown_public_key, &malformed_update_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_update_fail_htlc(&unkown_public_key, &fail_update_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_update_fulfill_htlc(&unkown_public_key, &fulfill_update_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_revoke_and_ack(&unkown_public_key, &revoke_and_ack_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+
+ nodes[1].node.handle_update_fee(&unkown_public_key, &update_fee_msg);
+ check_unkown_peer_msg_event(&nodes[1], unkown_public_key, channel_id);
+ }