@@ -198,6 +198,61 @@ fn expect_channel_shutdown_state_with_htlc() {
198198	assert ! ( nodes[ 0 ] . node. list_channels( ) . is_empty( ) ) ; 
199199} 
200200
201+ #[ test]  
202+ fn  test_lnd_bug_6039 ( )  { 
203+ 	// LND sends a nonsense error message any time it gets a shutdown if there are still HTLCs 
204+ 	// pending. We currently swallow that error to work around LND's bug #6039. This test emulates 
205+ 	// the LND nonsense and ensures we at least kinda handle it. 
206+ 	let  chanmon_cfgs = create_chanmon_cfgs ( 2 ) ; 
207+ 	let  node_cfgs = create_node_cfgs ( 2 ,  & chanmon_cfgs) ; 
208+ 	let  node_chanmgrs = create_node_chanmgrs ( 2 ,  & node_cfgs,  & [ None ,  None ] ) ; 
209+ 	let  mut  nodes = create_network ( 2 ,  & node_cfgs,  & node_chanmgrs) ; 
210+ 	let  chan = create_announced_chan_between_nodes ( & nodes,  0 ,  1 ) ; 
211+ 
212+ 	let  ( payment_preimage,  payment_hash,  _)  = route_payment ( & nodes[ 0 ] ,  & [ & nodes[ 1 ] ] ,  100_000 ) ; 
213+ 
214+ 	nodes[ 0 ] . node . close_channel ( & chan. 2 ,  & nodes[ 1 ] . node . get_our_node_id ( ) ) . unwrap ( ) ; 
215+ 	let  node_0_shutdown = get_event_msg ! ( nodes[ 0 ] ,  MessageSendEvent :: SendShutdown ,  nodes[ 1 ] . node. get_our_node_id( ) ) ; 
216+ 	nodes[ 1 ] . node . handle_shutdown ( & nodes[ 0 ] . node . get_our_node_id ( ) ,  & node_0_shutdown) ; 
217+ 
218+ 	// Generate an lnd-like error message and check that we respond by simply screaming louder to 
219+ 	// see if LND will accept our protocol compliance. 
220+ 	let  err_msg = msgs:: ErrorMessage  {  channel_id :  chan. 2 ,  data :  "link failed to shutdown" . to_string ( )  } ; 
221+ 	nodes[ 0 ] . node . handle_error ( & nodes[ 1 ] . node . get_our_node_id ( ) ,  & err_msg) ; 
222+ 	let  node_a_responses = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ; 
223+ 	assert_eq ! ( node_a_responses[ 0 ] ,  MessageSendEvent :: SendShutdown  { 
224+ 			node_id:  nodes[ 1 ] . node. get_our_node_id( ) , 
225+ 			msg:  node_0_shutdown, 
226+ 		} ) ; 
227+ 	if  let  MessageSendEvent :: HandleError  {  action :  msgs:: ErrorAction :: SendWarningMessage  {  .. } ,  .. } 
228+ 		= node_a_responses[ 1 ]  { }  else  {  panic ! ( ) ;  } 
229+ 
230+ 	let  node_1_shutdown = get_event_msg ! ( nodes[ 1 ] ,  MessageSendEvent :: SendShutdown ,  nodes[ 0 ] . node. get_our_node_id( ) ) ; 
231+ 
232+ 	assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ; 
233+ 	assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ; 
234+ 
235+ 	claim_payment ( & nodes[ 0 ] ,  & [ & nodes[ 1 ] ] ,  payment_preimage) ; 
236+ 
237+ 	// Assume that LND will eventually respond to our Shutdown if we clear all the remaining HTLCs 
238+ 	nodes[ 0 ] . node . handle_shutdown ( & nodes[ 1 ] . node . get_our_node_id ( ) ,  & node_1_shutdown) ; 
239+ 
240+ 	// ClosingSignNegotion process 
241+ 	let  node_0_closing_signed = get_event_msg ! ( nodes[ 0 ] ,  MessageSendEvent :: SendClosingSigned ,  nodes[ 1 ] . node. get_our_node_id( ) ) ; 
242+ 	nodes[ 1 ] . node . handle_closing_signed ( & nodes[ 0 ] . node . get_our_node_id ( ) ,  & node_0_closing_signed) ; 
243+ 	let  node_1_closing_signed = get_event_msg ! ( nodes[ 1 ] ,  MessageSendEvent :: SendClosingSigned ,  nodes[ 0 ] . node. get_our_node_id( ) ) ; 
244+ 	nodes[ 0 ] . node . handle_closing_signed ( & nodes[ 1 ] . node . get_our_node_id ( ) ,  & node_1_closing_signed) ; 
245+ 	let  ( _,  node_0_2nd_closing_signed)  = get_closing_signed_broadcast ! ( nodes[ 0 ] . node,  nodes[ 1 ] . node. get_our_node_id( ) ) ; 
246+ 	nodes[ 1 ] . node . handle_closing_signed ( & nodes[ 0 ] . node . get_our_node_id ( ) ,  & node_0_2nd_closing_signed. unwrap ( ) ) ; 
247+ 	let  ( _,  node_1_none)  = get_closing_signed_broadcast ! ( nodes[ 1 ] . node,  nodes[ 0 ] . node. get_our_node_id( ) ) ; 
248+ 	assert ! ( node_1_none. is_none( ) ) ; 
249+ 	check_closed_event ! ( nodes[ 0 ] ,  1 ,  ClosureReason :: CooperativeClosure ,  [ nodes[ 1 ] . node. get_our_node_id( ) ] ,  100000 ) ; 
250+ 	check_closed_event ! ( nodes[ 1 ] ,  1 ,  ClosureReason :: CooperativeClosure ,  [ nodes[ 0 ] . node. get_our_node_id( ) ] ,  100000 ) ; 
251+ 
252+ 	// Shutdown basically removes the channelDetails, testing of shutdowncomplete state unnecessary 
253+ 	assert ! ( nodes[ 0 ] . node. list_channels( ) . is_empty( ) ) ; 
254+ } 
255+ 
201256#[ test]  
202257fn  expect_channel_shutdown_state_with_force_closure ( )  { 
203258	// Test sending a shutdown prior to channel_ready after funding generation 
0 commit comments