@@ -29,7 +29,7 @@ use ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, Reply
29
29
use ln:: msgs;
30
30
use util:: ser:: { Writeable , Readable , Writer } ;
31
31
use util:: logger:: { Logger , Level } ;
32
- use util:: events:: { MessageSendEvent , MessageSendEventsProvider } ;
32
+ use util:: events:: { Event , EventHandler , MessageSendEvent , MessageSendEventsProvider } ;
33
33
use util:: scid_utils:: { block_from_scid, scid_from_parts, MAX_SCID_BLOCK } ;
34
34
35
35
use io;
@@ -103,6 +103,66 @@ impl_writeable_tlv_based_enum!(NetworkUpdate,
103
103
} ,
104
104
; ) ;
105
105
106
+ /// An [`EventHandler`] decorator for applying updates from [`Event::PaymentFailed`] to the
107
+ /// [`NetworkGraph`].
108
+ pub struct NetworkUpdateHandler < G : Deref < Target =NetworkGraph > , L : Deref , E : EventHandler >
109
+ where L :: Target : Logger {
110
+ secp_ctx : Secp256k1 < secp256k1:: VerifyOnly > ,
111
+ network_graph : G ,
112
+ logger : L ,
113
+ inner : E ,
114
+ }
115
+
116
+ impl < G : Deref < Target =NetworkGraph > , L : Deref , E : EventHandler > NetworkUpdateHandler < G , L , E >
117
+ where L :: Target : Logger {
118
+ /// Creates a handler that decorates `event_handler` with functionality for updating the given
119
+ /// `network_graph`.
120
+ pub fn new ( network_graph : G , logger : L , event_handler : E ) -> Self {
121
+ Self {
122
+ secp_ctx : Secp256k1 :: verification_only ( ) ,
123
+ network_graph,
124
+ logger,
125
+ inner : event_handler,
126
+ }
127
+ }
128
+
129
+ /// Applies changes to the [`NetworkGraph`] from the given update.
130
+ fn handle_network_update ( & self , update : & NetworkUpdate ) {
131
+ match * update {
132
+ NetworkUpdate :: ChannelUpdateMessage { ref msg } => {
133
+ let short_channel_id = msg. contents . short_channel_id ;
134
+ let is_enabled = msg. contents . flags & ( 1 << 1 ) != ( 1 << 1 ) ;
135
+ let status = if is_enabled { "enabled" } else { "disabled" } ;
136
+ log_debug ! ( self . logger, "Updating channel with channel_update from a payment failure. Channel {} is {}." , short_channel_id, status) ;
137
+ let _ = self . network_graph . update_channel ( msg, & self . secp_ctx ) ;
138
+ } ,
139
+ NetworkUpdate :: ChannelClosed { short_channel_id, is_permanent } => {
140
+ let action = if is_permanent { "Removing" } else { "Disabling" } ;
141
+ log_debug ! ( self . logger, "{} channel graph entry for {} due to a payment failure." , action, short_channel_id) ;
142
+ self . network_graph . close_channel_from_update ( short_channel_id, is_permanent) ;
143
+ } ,
144
+ NetworkUpdate :: NodeFailure { ref node_id, is_permanent } => {
145
+ let action = if is_permanent { "Removing" } else { "Disabling" } ;
146
+ log_debug ! ( self . logger, "{} node graph entry for {} due to a payment failure." , action, node_id) ;
147
+ self . network_graph . fail_node ( node_id, is_permanent) ;
148
+ } ,
149
+ }
150
+ }
151
+ }
152
+
153
+ impl < G : Deref < Target =NetworkGraph > , L : Deref , E : EventHandler > EventHandler for NetworkUpdateHandler < G , L , E >
154
+ where L :: Target : Logger {
155
+ fn handle_event ( & self , event : Event ) {
156
+ if let Event :: PaymentFailed { payment_hash : _, rejected_by_dest : _, network_update, .. } = & event {
157
+ if let Some ( network_update) = network_update {
158
+ self . handle_network_update ( network_update) ;
159
+ }
160
+ }
161
+
162
+ self . inner . handle_event ( event)
163
+ }
164
+ }
165
+
106
166
/// Receives and validates network updates from peers,
107
167
/// stores authentic and relevant data as a network graph.
108
168
/// This network graph is then used for routing payments.
@@ -1088,15 +1148,16 @@ impl NetworkGraph {
1088
1148
#[ cfg( test) ]
1089
1149
mod tests {
1090
1150
use chain;
1151
+ use ln:: PaymentHash ;
1091
1152
use ln:: features:: { ChannelFeatures , InitFeatures , NodeFeatures } ;
1092
- use routing:: network_graph:: { NetGraphMsgHandler , NetworkGraph , MAX_EXCESS_BYTES_FOR_RELAY } ;
1153
+ use routing:: network_graph:: { NetGraphMsgHandler , NetworkGraph , NetworkUpdate , NetworkUpdateHandler , MAX_EXCESS_BYTES_FOR_RELAY } ;
1093
1154
use ln:: msgs:: { Init , OptionalField , RoutingMessageHandler , UnsignedNodeAnnouncement , NodeAnnouncement ,
1094
1155
UnsignedChannelAnnouncement , ChannelAnnouncement , UnsignedChannelUpdate , ChannelUpdate ,
1095
1156
ReplyChannelRange , ReplyShortChannelIdsEnd , QueryChannelRange , QueryShortChannelIds , MAX_VALUE_MSAT } ;
1096
1157
use util:: test_utils;
1097
1158
use util:: logger:: Logger ;
1098
1159
use util:: ser:: { Readable , Writeable } ;
1099
- use util:: events:: { MessageSendEvent , MessageSendEventsProvider } ;
1160
+ use util:: events:: { Event , EventHandler , MessageSendEvent , MessageSendEventsProvider } ;
1100
1161
use util:: scid_utils:: scid_from_parts;
1101
1162
1102
1163
use bitcoin:: hashes:: sha256d:: Hash as Sha256dHash ;
@@ -1593,8 +1654,13 @@ mod tests {
1593
1654
}
1594
1655
1595
1656
#[ test]
1596
- fn handling_htlc_fail_channel_update ( ) {
1597
- let ( secp_ctx, net_graph_msg_handler) = create_net_graph_msg_handler ( ) ;
1657
+ fn handling_network_update ( ) {
1658
+ let logger = test_utils:: TestLogger :: new ( ) ;
1659
+ let genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
1660
+ let network_graph = NetworkGraph :: new ( genesis_hash) ;
1661
+ let handler = NetworkUpdateHandler :: new ( & network_graph, & logger, |_| { } ) ;
1662
+ let secp_ctx = Secp256k1 :: new ( ) ;
1663
+
1598
1664
let node_1_privkey = & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ;
1599
1665
let node_2_privkey = & SecretKey :: from_slice ( & [ 41 ; 32 ] ) . unwrap ( ) ;
1600
1666
let node_id_1 = PublicKey :: from_secret_key ( & secp_ctx, node_1_privkey) ;
@@ -1607,8 +1673,7 @@ mod tests {
1607
1673
1608
1674
{
1609
1675
// There is no nodes in the table at the beginning.
1610
- let network = & net_graph_msg_handler. network_graph ;
1611
- assert_eq ! ( network. get_nodes( ) . len( ) , 0 ) ;
1676
+ assert_eq ! ( network_graph. get_nodes( ) . len( ) , 0 ) ;
1612
1677
}
1613
1678
1614
1679
{
@@ -1632,10 +1697,9 @@ mod tests {
1632
1697
bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_2_btckey) ,
1633
1698
contents : unsigned_announcement. clone ( ) ,
1634
1699
} ;
1635
- match net_graph_msg_handler. handle_channel_announcement ( & valid_channel_announcement) {
1636
- Ok ( _) => ( ) ,
1637
- Err ( _) => panic ! ( )
1638
- } ;
1700
+ let chain_source: Option < & test_utils:: TestChainSource > = None ;
1701
+ assert ! ( network_graph. update_channel_from_announcement( & valid_channel_announcement, & chain_source, & secp_ctx) . is_ok( ) ) ;
1702
+ assert ! ( network_graph. get_channels( ) . get( & short_channel_id) . is_some( ) ) ;
1639
1703
1640
1704
let unsigned_channel_update = UnsignedChannelUpdate {
1641
1705
chain_hash,
@@ -1655,44 +1719,65 @@ mod tests {
1655
1719
contents : unsigned_channel_update. clone ( )
1656
1720
} ;
1657
1721
1658
- match net_graph_msg_handler. handle_channel_update ( & valid_channel_update) {
1659
- Ok ( res) => assert ! ( res) ,
1660
- _ => panic ! ( )
1661
- } ;
1722
+ assert ! ( network_graph. get_channels( ) . get( & short_channel_id) . unwrap( ) . one_to_two. is_none( ) ) ;
1723
+
1724
+ handler. handle_event ( Event :: PaymentFailed {
1725
+ payment_hash : PaymentHash ( [ 0 ; 32 ] ) ,
1726
+ rejected_by_dest : false ,
1727
+ network_update : Some ( NetworkUpdate :: ChannelUpdateMessage {
1728
+ msg : valid_channel_update,
1729
+ } ) ,
1730
+ error_code : None ,
1731
+ error_data : None ,
1732
+ } ) ;
1733
+
1734
+ assert ! ( network_graph. get_channels( ) . get( & short_channel_id) . unwrap( ) . one_to_two. is_some( ) ) ;
1662
1735
}
1663
1736
1664
1737
// Non-permanent closing just disables a channel
1665
1738
{
1666
- let network = & net_graph_msg_handler. network_graph ;
1667
- match network. get_channels ( ) . get ( & short_channel_id) {
1739
+ match network_graph. get_channels ( ) . get ( & short_channel_id) {
1668
1740
None => panic ! ( ) ,
1669
1741
Some ( channel_info) => {
1670
- assert ! ( channel_info. one_to_two. is_some ( ) ) ;
1742
+ assert ! ( channel_info. one_to_two. as_ref ( ) . unwrap ( ) . enabled ) ;
1671
1743
}
1672
1744
} ;
1673
- }
1674
1745
1675
- net_graph_msg_handler. network_graph . close_channel_from_update ( short_channel_id, false ) ;
1746
+ handler. handle_event ( Event :: PaymentFailed {
1747
+ payment_hash : PaymentHash ( [ 0 ; 32 ] ) ,
1748
+ rejected_by_dest : false ,
1749
+ network_update : Some ( NetworkUpdate :: ChannelClosed {
1750
+ short_channel_id,
1751
+ is_permanent : false ,
1752
+ } ) ,
1753
+ error_code : None ,
1754
+ error_data : None ,
1755
+ } ) ;
1676
1756
1677
- // Non-permanent closing just disables a channel
1678
- {
1679
- let network = & net_graph_msg_handler. network_graph ;
1680
- match network. get_channels ( ) . get ( & short_channel_id) {
1757
+ match network_graph. get_channels ( ) . get ( & short_channel_id) {
1681
1758
None => panic ! ( ) ,
1682
1759
Some ( channel_info) => {
1683
1760
assert ! ( !channel_info. one_to_two. as_ref( ) . unwrap( ) . enabled) ;
1684
1761
}
1685
1762
} ;
1686
1763
}
1687
1764
1688
- net_graph_msg_handler. network_graph . close_channel_from_update ( short_channel_id, true ) ;
1689
-
1690
1765
// Permanent closing deletes a channel
1691
1766
{
1692
- let network = & net_graph_msg_handler. network_graph ;
1693
- assert_eq ! ( network. get_channels( ) . len( ) , 0 ) ;
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 : true ,
1773
+ } ) ,
1774
+ error_code : None ,
1775
+ error_data : None ,
1776
+ } ) ;
1777
+
1778
+ assert_eq ! ( network_graph. get_channels( ) . len( ) , 0 ) ;
1694
1779
// Nodes are also deleted because there are no associated channels anymore
1695
- assert_eq ! ( network . get_nodes( ) . len( ) , 0 ) ;
1780
+ assert_eq ! ( network_graph . get_nodes( ) . len( ) , 0 ) ;
1696
1781
}
1697
1782
// TODO: Test NetworkUpdate::NodeFailure, which is not implemented yet.
1698
1783
}
@@ -2473,6 +2558,30 @@ mod tests {
2473
2558
} ) ;
2474
2559
assert ! ( result. is_err( ) ) ;
2475
2560
}
2561
+
2562
+ #[ test]
2563
+ fn delegates_to_decorated_event_handler ( ) {
2564
+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
2565
+
2566
+ {
2567
+ let logger = test_utils:: TestLogger :: new ( ) ;
2568
+ let genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
2569
+ let network_graph = NetworkGraph :: new ( genesis_hash) ;
2570
+
2571
+ let handler = NetworkUpdateHandler :: new ( & network_graph, & logger, |_| {
2572
+ * event_handled. borrow_mut ( ) = true ;
2573
+ } ) ;
2574
+ handler. handle_event ( Event :: PaymentFailed {
2575
+ payment_hash : PaymentHash ( [ 0 ; 32 ] ) ,
2576
+ rejected_by_dest : false ,
2577
+ network_update : None ,
2578
+ error_code : None ,
2579
+ error_data : None ,
2580
+ } ) ;
2581
+ }
2582
+
2583
+ assert ! ( event_handled. into_inner( ) ) ;
2584
+ }
2476
2585
}
2477
2586
2478
2587
#[ cfg( all( test, feature = "unstable" ) ) ]
0 commit comments