|
1 | 1 | use crate::chain::ChannelMonitorUpdateStatus;
|
| 2 | +use crate::events::Event; |
2 | 3 | use crate::events::HTLCDestination;
|
3 | 4 | use crate::events::MessageSendEvent;
|
4 | 5 | use crate::events::MessageSendEventsProvider;
|
@@ -284,3 +285,131 @@ fn test_quiescence_tracks_monitor_update_in_progress_and_waits_for_async_signer(
|
284 | 285 | let _ = get_htlc_update_msgs!(&nodes[0], node_id_1);
|
285 | 286 | check_added_monitors(&nodes[0], 1);
|
286 | 287 | }
|
| 288 | + |
| 289 | +#[test] |
| 290 | +fn test_quiescence_updates_go_to_holding_cell() { |
| 291 | + quiescence_updates_go_to_holding_cell(false); |
| 292 | + quiescence_updates_go_to_holding_cell(true); |
| 293 | +} |
| 294 | + |
| 295 | +fn quiescence_updates_go_to_holding_cell(fail_htlc: bool) { |
| 296 | + // Test that any updates made to a channel while quiescent go to the holding cell. |
| 297 | + let chanmon_cfgs = create_chanmon_cfgs(2); |
| 298 | + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); |
| 299 | + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); |
| 300 | + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); |
| 301 | + let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2; |
| 302 | + |
| 303 | + let node_id_0 = nodes[0].node.get_our_node_id(); |
| 304 | + let node_id_1 = nodes[1].node.get_our_node_id(); |
| 305 | + |
| 306 | + // Send enough to be able to pay from both directions. |
| 307 | + let payment_amount = 1_000_000; |
| 308 | + send_payment(&nodes[0], &[&nodes[1]], payment_amount * 4); |
| 309 | + |
| 310 | + // Propose quiescence from nodes[1], and immediately try to send a payment. Since its `stfu` has |
| 311 | + // already gone out first, the outbound HTLC will go into the holding cell. |
| 312 | + nodes[1].node.maybe_propose_quiescence(&node_id_0, &chan_id).unwrap(); |
| 313 | + let stfu = get_event_msg!(&nodes[1], MessageSendEvent::SendStfu, node_id_0); |
| 314 | + |
| 315 | + let (route1, payment_hash1, payment_preimage1, payment_secret1) = |
| 316 | + get_route_and_payment_hash!(&nodes[1], &nodes[0], payment_amount); |
| 317 | + let onion1 = RecipientOnionFields::secret_only(payment_secret1); |
| 318 | + let payment_id1 = PaymentId(payment_hash1.0); |
| 319 | + nodes[1].node.send_payment_with_route(route1, payment_hash1, onion1, payment_id1).unwrap(); |
| 320 | + check_added_monitors!(&nodes[1], 0); |
| 321 | + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); |
| 322 | + |
| 323 | + // Send a payment in the opposite direction. Since nodes[0] hasn't sent its own `stfu` yet, it's |
| 324 | + // allowed to make updates. |
| 325 | + let (route2, payment_hash2, payment_preimage2, payment_secret2) = |
| 326 | + get_route_and_payment_hash!(&nodes[0], &nodes[1], payment_amount); |
| 327 | + let onion2 = RecipientOnionFields::secret_only(payment_secret2); |
| 328 | + let payment_id2 = PaymentId(payment_hash2.0); |
| 329 | + nodes[0].node.send_payment_with_route(route2, payment_hash2, onion2, payment_id2).unwrap(); |
| 330 | + check_added_monitors!(&nodes[0], 1); |
| 331 | + |
| 332 | + let update_add = get_htlc_update_msgs!(&nodes[0], node_id_1); |
| 333 | + nodes[1].node.handle_update_add_htlc(node_id_0, &update_add.update_add_htlcs[0]); |
| 334 | + commitment_signed_dance!(&nodes[1], &nodes[0], update_add.commitment_signed, false); |
| 335 | + expect_pending_htlcs_forwardable!(&nodes[1]); |
| 336 | + expect_payment_claimable!(nodes[1], payment_hash2, payment_secret2, payment_amount); |
| 337 | + |
| 338 | + // Have nodes[1] attempt to fail/claim nodes[0]'s payment. Since nodes[1] already sent out |
| 339 | + // `stfu`, the `update_fail/fulfill` will go into the holding cell. |
| 340 | + if fail_htlc { |
| 341 | + nodes[1].node.fail_htlc_backwards(&payment_hash2); |
| 342 | + let failed_payment = HTLCDestination::FailedPayment { payment_hash: payment_hash2 }; |
| 343 | + expect_pending_htlcs_forwardable_and_htlc_handling_failed!(&nodes[1], vec![failed_payment]); |
| 344 | + } else { |
| 345 | + nodes[1].node.claim_funds(payment_preimage2); |
| 346 | + check_added_monitors(&nodes[1], 1); |
| 347 | + } |
| 348 | + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); |
| 349 | + |
| 350 | + // Finish the quiescence handshake. |
| 351 | + nodes[0].node.handle_stfu(node_id_1, &stfu); |
| 352 | + let stfu = get_event_msg!(&nodes[0], MessageSendEvent::SendStfu, node_id_1); |
| 353 | + nodes[1].node.handle_stfu(node_id_0, &stfu); |
| 354 | + |
| 355 | + nodes[0].node.exit_quiescence(&node_id_1, &chan_id).unwrap(); |
| 356 | + nodes[1].node.exit_quiescence(&node_id_0, &chan_id).unwrap(); |
| 357 | + |
| 358 | + // Now that quiescence is over, nodes are allowed to make updates again. nodes[1] will have its |
| 359 | + // outbound HTLC finally go out, along with the fail/claim of nodes[0]'s payment. |
| 360 | + let update = get_htlc_update_msgs!(&nodes[1], node_id_0); |
| 361 | + check_added_monitors(&nodes[1], 1); |
| 362 | + nodes[0].node.handle_update_add_htlc(node_id_1, &update.update_add_htlcs[0]); |
| 363 | + if fail_htlc { |
| 364 | + nodes[0].node.handle_update_fail_htlc(node_id_1, &update.update_fail_htlcs[0]); |
| 365 | + } else { |
| 366 | + nodes[0].node.handle_update_fulfill_htlc(node_id_1, &update.update_fulfill_htlcs[0]); |
| 367 | + } |
| 368 | + commitment_signed_dance!(&nodes[0], &nodes[1], update.commitment_signed, false); |
| 369 | + |
| 370 | + if !fail_htlc { |
| 371 | + expect_payment_claimed!(nodes[1], payment_hash2, payment_amount); |
| 372 | + } |
| 373 | + |
| 374 | + // The payment from nodes[0] should now be seen as failed/successful. |
| 375 | + let events = nodes[0].node.get_and_clear_pending_events(); |
| 376 | + assert_eq!(events.len(), 3); |
| 377 | + assert!(events.iter().find(|e| matches!(e, Event::PendingHTLCsForwardable { .. })).is_some()); |
| 378 | + if fail_htlc { |
| 379 | + assert!(events.iter().find(|e| matches!(e, Event::PaymentFailed { .. })).is_some()); |
| 380 | + assert!(events.iter().find(|e| matches!(e, Event::PaymentPathFailed { .. })).is_some()); |
| 381 | + } else { |
| 382 | + assert!(events.iter().find(|e| matches!(e, Event::PaymentSent { .. })).is_some()); |
| 383 | + assert!(events.iter().find(|e| matches!(e, Event::PaymentPathSuccessful { .. })).is_some()); |
| 384 | + check_added_monitors(&nodes[0], 1); |
| 385 | + } |
| 386 | + nodes[0].node.process_pending_htlc_forwards(); |
| 387 | + expect_payment_claimable!(nodes[0], payment_hash1, payment_secret1, payment_amount); |
| 388 | + |
| 389 | + // Have nodes[0] fail/claim nodes[1]'s payment. |
| 390 | + if fail_htlc { |
| 391 | + nodes[0].node.fail_htlc_backwards(&payment_hash1); |
| 392 | + let failed_payment = HTLCDestination::FailedPayment { payment_hash: payment_hash1 }; |
| 393 | + expect_pending_htlcs_forwardable_and_htlc_handling_failed!(&nodes[0], vec![failed_payment]); |
| 394 | + } else { |
| 395 | + nodes[0].node.claim_funds(payment_preimage1); |
| 396 | + } |
| 397 | + check_added_monitors(&nodes[0], 1); |
| 398 | + |
| 399 | + let update = get_htlc_update_msgs!(&nodes[0], node_id_1); |
| 400 | + if fail_htlc { |
| 401 | + nodes[1].node.handle_update_fail_htlc(node_id_0, &update.update_fail_htlcs[0]); |
| 402 | + } else { |
| 403 | + nodes[1].node.handle_update_fulfill_htlc(node_id_0, &update.update_fulfill_htlcs[0]); |
| 404 | + } |
| 405 | + commitment_signed_dance!(&nodes[1], &nodes[0], update.commitment_signed, false); |
| 406 | + |
| 407 | + // The payment from nodes[1] should now be seen as failed/successful. |
| 408 | + if fail_htlc { |
| 409 | + let conditions = PaymentFailedConditions::new(); |
| 410 | + expect_payment_failed_conditions(&nodes[1], payment_hash1, true, conditions); |
| 411 | + } else { |
| 412 | + expect_payment_claimed!(nodes[0], payment_hash1, payment_amount); |
| 413 | + expect_payment_sent(&nodes[1], payment_preimage1, None, true, true); |
| 414 | + } |
| 415 | +} |
0 commit comments