@@ -29,7 +29,7 @@ use ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, Reply
2929use  ln:: msgs; 
3030use  util:: ser:: { Writeable ,  Readable ,  Writer } ; 
3131use  util:: logger:: { Logger ,  Level } ; 
32- use  util:: events:: { MessageSendEvent ,  MessageSendEventsProvider } ; 
32+ use  util:: events:: { Event ,   EventHandler ,   MessageSendEvent ,  MessageSendEventsProvider } ; 
3333use  util:: scid_utils:: { block_from_scid,  scid_from_parts,  MAX_SCID_BLOCK } ; 
3434
3535use  io; 
@@ -110,6 +110,66 @@ impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate,
110110	} , 
111111) ; 
112112
113+ /// An [`EventHandler`] decorator for applying updates from [`Event::PaymentFailed`] to the 
114+ /// [`NetworkGraph`]. 
115+ pub  struct  NetworkUpdateHandler < G :  Deref < Target =NetworkGraph > ,  L :  Deref ,  E :  EventHandler > 
116+ where  L :: Target :  Logger  { 
117+ 	secp_ctx :  Secp256k1 < secp256k1:: VerifyOnly > , 
118+ 	network_graph :  G , 
119+ 	logger :  L , 
120+ 	inner :  E , 
121+ } 
122+ 
123+ impl < G :  Deref < Target =NetworkGraph > ,  L :  Deref ,  E :  EventHandler >  NetworkUpdateHandler < G ,  L ,  E > 
124+ where  L :: Target :  Logger  { 
125+ 	/// Creates a handler that decorates `event_handler` with functionality for updating the given 
126+ /// `network_graph`. 
127+ pub  fn  new ( network_graph :  G ,  logger :  L ,  event_handler :  E )  -> Self  { 
128+ 		Self  { 
129+ 			secp_ctx :  Secp256k1 :: verification_only ( ) , 
130+ 			network_graph, 
131+ 			logger, 
132+ 			inner :  event_handler, 
133+ 		} 
134+ 	} 
135+ 
136+ 	/// Applies changes to the [`NetworkGraph`] from the given update. 
137+ fn  handle_network_update ( & self ,  update :  & NetworkUpdate )  { 
138+ 		match  * update { 
139+ 			NetworkUpdate :: ChannelUpdateMessage  {  ref  msg }  => { 
140+ 				let  short_channel_id = msg. contents . short_channel_id ; 
141+ 				let  is_enabled = msg. contents . flags  &  ( 1  << 1 )  != ( 1  << 1 ) ; 
142+ 				let  status = if  is_enabled {  "enabled"  }  else  {  "disabled"  } ; 
143+ 				log_debug ! ( self . logger,  "Updating channel with channel_update from a payment failure. Channel {} is {}." ,  short_channel_id,  status) ; 
144+ 				let  _ = self . network_graph . update_channel ( msg,  & self . secp_ctx ) ; 
145+ 			} , 
146+ 			NetworkUpdate :: ChannelClosed  {  short_channel_id,  is_permanent }  => { 
147+ 				let  action = if  is_permanent {  "Removing"  }  else  {  "Disabling"  } ; 
148+ 				log_debug ! ( self . logger,  "{} channel graph entry for {} due to a payment failure." ,  action,  short_channel_id) ; 
149+ 				self . network_graph . close_channel_from_update ( short_channel_id,  is_permanent) ; 
150+ 			} , 
151+ 			NetworkUpdate :: NodeFailure  {  ref  node_id,  is_permanent }  => { 
152+ 				let  action = if  is_permanent {  "Removing"  }  else  {  "Disabling"  } ; 
153+ 				log_debug ! ( self . logger,  "{} node graph entry for {} due to a payment failure." ,  action,  node_id) ; 
154+ 				self . network_graph . fail_node ( node_id,  is_permanent) ; 
155+ 			} , 
156+ 		} 
157+ 	} 
158+ } 
159+ 
160+ impl < G :  Deref < Target =NetworkGraph > ,  L :  Deref ,  E :  EventHandler >  EventHandler  for  NetworkUpdateHandler < G ,  L ,  E > 
161+ where  L :: Target :  Logger  { 
162+ 	fn  handle_event ( & self ,  event :  & Event )  { 
163+ 		if  let  Event :: PaymentFailed  {  payment_hash :  _,  rejected_by_dest :  _,  network_update,  .. }  = event { 
164+ 			if  let  Some ( network_update)  = network_update { 
165+ 				self . handle_network_update ( network_update) ; 
166+ 			} 
167+ 		} 
168+ 
169+ 		self . inner . handle_event ( event) 
170+ 	} 
171+ } 
172+ 
113173/// Receives and validates network updates from peers, 
114174/// stores authentic and relevant data as a network graph. 
115175/// This network graph is then used for routing payments. 
@@ -1109,15 +1169,16 @@ impl ReadOnlyNetworkGraph<'_> {
11091169#[ cfg( test) ]  
11101170mod  tests { 
11111171	use  chain; 
1172+ 	use  ln:: PaymentHash ; 
11121173	use  ln:: features:: { ChannelFeatures ,  InitFeatures ,  NodeFeatures } ; 
1113- 	use  routing:: network_graph:: { NetGraphMsgHandler ,  NetworkGraph ,  MAX_EXCESS_BYTES_FOR_RELAY } ; 
1174+ 	use  routing:: network_graph:: { NetGraphMsgHandler ,  NetworkGraph ,  NetworkUpdate ,   NetworkUpdateHandler ,   MAX_EXCESS_BYTES_FOR_RELAY } ; 
11141175	use  ln:: msgs:: { Init ,  OptionalField ,  RoutingMessageHandler ,  UnsignedNodeAnnouncement ,  NodeAnnouncement , 
11151176		UnsignedChannelAnnouncement ,  ChannelAnnouncement ,  UnsignedChannelUpdate ,  ChannelUpdate ,  
11161177		ReplyChannelRange ,  ReplyShortChannelIdsEnd ,  QueryChannelRange ,  QueryShortChannelIds ,  MAX_VALUE_MSAT } ; 
11171178	use  util:: test_utils; 
11181179	use  util:: logger:: Logger ; 
11191180	use  util:: ser:: { Readable ,  Writeable } ; 
1120- 	use  util:: events:: { MessageSendEvent ,  MessageSendEventsProvider } ; 
1181+ 	use  util:: events:: { Event ,   EventHandler ,   MessageSendEvent ,  MessageSendEventsProvider } ; 
11211182	use  util:: scid_utils:: scid_from_parts; 
11221183
11231184	use  bitcoin:: hashes:: sha256d:: Hash  as  Sha256dHash ; 
@@ -1614,8 +1675,13 @@ mod tests {
16141675	} 
16151676
16161677	#[ test]  
1617- 	fn  handling_htlc_fail_channel_update ( )  { 
1618- 		let  ( secp_ctx,  net_graph_msg_handler)  = create_net_graph_msg_handler ( ) ; 
1678+ 	fn  handling_network_update ( )  { 
1679+ 		let  logger = test_utils:: TestLogger :: new ( ) ; 
1680+ 		let  genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ; 
1681+ 		let  network_graph = NetworkGraph :: new ( genesis_hash) ; 
1682+ 		let  handler = NetworkUpdateHandler :: new ( & network_graph,  & logger,  |_:  & _ | { } ) ; 
1683+ 		let  secp_ctx = Secp256k1 :: new ( ) ; 
1684+ 
16191685		let  node_1_privkey = & SecretKey :: from_slice ( & [ 42 ;  32 ] ) . unwrap ( ) ; 
16201686		let  node_2_privkey = & SecretKey :: from_slice ( & [ 41 ;  32 ] ) . unwrap ( ) ; 
16211687		let  node_id_1 = PublicKey :: from_secret_key ( & secp_ctx,  node_1_privkey) ; 
@@ -1628,8 +1694,7 @@ mod tests {
16281694
16291695		{ 
16301696			// There is no nodes in the table at the beginning. 
1631- 			let  network = & net_graph_msg_handler. network_graph ; 
1632- 			assert_eq ! ( network. read_only( ) . nodes( ) . len( ) ,  0 ) ; 
1697+ 			assert_eq ! ( network_graph. read_only( ) . nodes( ) . len( ) ,  0 ) ; 
16331698		} 
16341699
16351700		{ 
@@ -1653,10 +1718,9 @@ mod tests {
16531718				bitcoin_signature_2 :  secp_ctx. sign ( & msghash,  node_2_btckey) , 
16541719				contents :  unsigned_announcement. clone ( ) , 
16551720			} ; 
1656- 			match  net_graph_msg_handler. handle_channel_announcement ( & valid_channel_announcement)  { 
1657- 				Ok ( _)  => ( ) , 
1658- 				Err ( _)  => panic ! ( ) 
1659- 			} ; 
1721+ 			let  chain_source:  Option < & test_utils:: TestChainSource >  = None ; 
1722+ 			assert ! ( network_graph. update_channel_from_announcement( & valid_channel_announcement,  & chain_source,  & secp_ctx) . is_ok( ) ) ; 
1723+ 			assert ! ( network_graph. read_only( ) . channels( ) . get( & short_channel_id) . is_some( ) ) ; 
16601724
16611725			let  unsigned_channel_update = UnsignedChannelUpdate  { 
16621726				chain_hash, 
@@ -1676,44 +1740,65 @@ mod tests {
16761740				contents :  unsigned_channel_update. clone ( ) 
16771741			} ; 
16781742
1679- 			match  net_graph_msg_handler. handle_channel_update ( & valid_channel_update)  { 
1680- 				Ok ( res)  => assert ! ( res) , 
1681- 				_ => panic ! ( ) 
1682- 			} ; 
1743+ 			assert ! ( network_graph. read_only( ) . channels( ) . get( & short_channel_id) . unwrap( ) . one_to_two. is_none( ) ) ; 
1744+ 
1745+ 			handler. handle_event ( & Event :: PaymentFailed  { 
1746+ 				payment_hash :  PaymentHash ( [ 0 ;  32 ] ) , 
1747+ 				rejected_by_dest :  false , 
1748+ 				network_update :  Some ( NetworkUpdate :: ChannelUpdateMessage  { 
1749+ 					msg :  valid_channel_update, 
1750+ 				} ) , 
1751+ 				error_code :  None , 
1752+ 				error_data :  None , 
1753+ 			} ) ; 
1754+ 
1755+ 			assert ! ( network_graph. read_only( ) . channels( ) . get( & short_channel_id) . unwrap( ) . one_to_two. is_some( ) ) ; 
16831756		} 
16841757
16851758		// Non-permanent closing just disables a channel 
16861759		{ 
1687- 			let  network = & net_graph_msg_handler. network_graph ; 
1688- 			match  network. read_only ( ) . channels ( ) . get ( & short_channel_id)  { 
1760+ 			match  network_graph. read_only ( ) . channels ( ) . get ( & short_channel_id)  { 
16891761				None  => panic ! ( ) , 
16901762				Some ( channel_info)  => { 
1691- 					assert ! ( channel_info. one_to_two. is_some ( ) ) ; 
1763+ 					assert ! ( channel_info. one_to_two. as_ref ( ) . unwrap ( ) . enabled ) ; 
16921764				} 
16931765			} ; 
1694- 		} 
16951766
1696- 		net_graph_msg_handler. network_graph . close_channel_from_update ( short_channel_id,  false ) ; 
1767+ 			handler. handle_event ( & Event :: PaymentFailed  { 
1768+ 				payment_hash :  PaymentHash ( [ 0 ;  32 ] ) , 
1769+ 				rejected_by_dest :  false , 
1770+ 				network_update :  Some ( NetworkUpdate :: ChannelClosed  { 
1771+ 					short_channel_id, 
1772+ 					is_permanent :  false , 
1773+ 				} ) , 
1774+ 				error_code :  None , 
1775+ 				error_data :  None , 
1776+ 			} ) ; 
16971777
1698- 		// Non-permanent closing just disables a channel 
1699- 		{ 
1700- 			let  network = & net_graph_msg_handler. network_graph ; 
1701- 			match  network. read_only ( ) . channels ( ) . get ( & short_channel_id)  { 
1778+ 			match  network_graph. read_only ( ) . channels ( ) . get ( & short_channel_id)  { 
17021779				None  => panic ! ( ) , 
17031780				Some ( channel_info)  => { 
17041781					assert ! ( !channel_info. one_to_two. as_ref( ) . unwrap( ) . enabled) ; 
17051782				} 
17061783			} ; 
17071784		} 
17081785
1709- 		net_graph_msg_handler. network_graph . close_channel_from_update ( short_channel_id,  true ) ; 
1710- 
17111786		// Permanent closing deletes a channel 
17121787		{ 
1713- 			let  network = & net_graph_msg_handler. network_graph ; 
1714- 			assert_eq ! ( network. read_only( ) . channels( ) . len( ) ,  0 ) ; 
1788+ 			handler. handle_event ( & Event :: PaymentFailed  { 
1789+ 				payment_hash :  PaymentHash ( [ 0 ;  32 ] ) , 
1790+ 				rejected_by_dest :  false , 
1791+ 				network_update :  Some ( NetworkUpdate :: ChannelClosed  { 
1792+ 					short_channel_id, 
1793+ 					is_permanent :  true , 
1794+ 				} ) , 
1795+ 				error_code :  None , 
1796+ 				error_data :  None , 
1797+ 			} ) ; 
1798+ 
1799+ 			assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) ,  0 ) ; 
17151800			// Nodes are also deleted because there are no associated channels anymore 
1716- 			assert_eq ! ( network . read_only( ) . nodes( ) . len( ) ,  0 ) ; 
1801+ 			assert_eq ! ( network_graph . read_only( ) . nodes( ) . len( ) ,  0 ) ; 
17171802		} 
17181803		// TODO: Test NetworkUpdate::NodeFailure, which is not implemented yet. 
17191804	} 
@@ -2494,6 +2579,30 @@ mod tests {
24942579		} ) ; 
24952580		assert ! ( result. is_err( ) ) ; 
24962581	} 
2582+ 
2583+ 	#[ test]  
2584+ 	fn  delegates_to_decorated_event_handler ( )  { 
2585+ 		let  event_handled = core:: cell:: RefCell :: new ( false ) ; 
2586+ 
2587+ 		{ 
2588+ 			let  logger = test_utils:: TestLogger :: new ( ) ; 
2589+ 			let  genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ; 
2590+ 			let  network_graph = NetworkGraph :: new ( genesis_hash) ; 
2591+ 
2592+ 			let  handler = NetworkUpdateHandler :: new ( & network_graph,  & logger,  |_:  & _ | { 
2593+ 				* event_handled. borrow_mut ( )  = true ; 
2594+ 			} ) ; 
2595+ 			handler. handle_event ( & Event :: PaymentFailed  { 
2596+ 				payment_hash :  PaymentHash ( [ 0 ;  32 ] ) , 
2597+ 				rejected_by_dest :  false , 
2598+ 				network_update :  None , 
2599+ 				error_code :  None , 
2600+ 				error_data :  None , 
2601+ 			} ) ; 
2602+ 		} 
2603+ 
2604+ 		assert ! ( event_handled. into_inner( ) ) ; 
2605+ 	} 
24972606} 
24982607
24992608#[ cfg( all( test,  feature = "unstable" ) ) ]  
0 commit comments