@@ -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;
@@ -110,6 +110,66 @@ impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate,
110
110
} ,
111
111
) ;
112
112
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
+
113
173
/// Receives and validates network updates from peers,
114
174
/// stores authentic and relevant data as a network graph.
115
175
/// This network graph is then used for routing payments.
@@ -1109,15 +1169,16 @@ impl ReadOnlyNetworkGraph<'_> {
1109
1169
#[ cfg( test) ]
1110
1170
mod tests {
1111
1171
use chain;
1172
+ use ln:: PaymentHash ;
1112
1173
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 } ;
1114
1175
use ln:: msgs:: { Init , OptionalField , RoutingMessageHandler , UnsignedNodeAnnouncement , NodeAnnouncement ,
1115
1176
UnsignedChannelAnnouncement , ChannelAnnouncement , UnsignedChannelUpdate , ChannelUpdate ,
1116
1177
ReplyChannelRange , ReplyShortChannelIdsEnd , QueryChannelRange , QueryShortChannelIds , MAX_VALUE_MSAT } ;
1117
1178
use util:: test_utils;
1118
1179
use util:: logger:: Logger ;
1119
1180
use util:: ser:: { Readable , Writeable } ;
1120
- use util:: events:: { MessageSendEvent , MessageSendEventsProvider } ;
1181
+ use util:: events:: { Event , EventHandler , MessageSendEvent , MessageSendEventsProvider } ;
1121
1182
use util:: scid_utils:: scid_from_parts;
1122
1183
1123
1184
use bitcoin:: hashes:: sha256d:: Hash as Sha256dHash ;
@@ -1614,8 +1675,13 @@ mod tests {
1614
1675
}
1615
1676
1616
1677
#[ 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
+
1619
1685
let node_1_privkey = & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ;
1620
1686
let node_2_privkey = & SecretKey :: from_slice ( & [ 41 ; 32 ] ) . unwrap ( ) ;
1621
1687
let node_id_1 = PublicKey :: from_secret_key ( & secp_ctx, node_1_privkey) ;
@@ -1628,8 +1694,7 @@ mod tests {
1628
1694
1629
1695
{
1630
1696
// 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 ) ;
1633
1698
}
1634
1699
1635
1700
{
@@ -1653,10 +1718,9 @@ mod tests {
1653
1718
bitcoin_signature_2 : secp_ctx. sign ( & msghash, node_2_btckey) ,
1654
1719
contents : unsigned_announcement. clone ( ) ,
1655
1720
} ;
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( ) ) ;
1660
1724
1661
1725
let unsigned_channel_update = UnsignedChannelUpdate {
1662
1726
chain_hash,
@@ -1676,44 +1740,65 @@ mod tests {
1676
1740
contents : unsigned_channel_update. clone ( )
1677
1741
} ;
1678
1742
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( ) ) ;
1683
1756
}
1684
1757
1685
1758
// Non-permanent closing just disables a channel
1686
1759
{
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) {
1689
1761
None => panic ! ( ) ,
1690
1762
Some ( channel_info) => {
1691
- assert ! ( channel_info. one_to_two. is_some ( ) ) ;
1763
+ assert ! ( channel_info. one_to_two. as_ref ( ) . unwrap ( ) . enabled ) ;
1692
1764
}
1693
1765
} ;
1694
- }
1695
1766
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
+ } ) ;
1697
1777
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) {
1702
1779
None => panic ! ( ) ,
1703
1780
Some ( channel_info) => {
1704
1781
assert ! ( !channel_info. one_to_two. as_ref( ) . unwrap( ) . enabled) ;
1705
1782
}
1706
1783
} ;
1707
1784
}
1708
1785
1709
- net_graph_msg_handler. network_graph . close_channel_from_update ( short_channel_id, true ) ;
1710
-
1711
1786
// Permanent closing deletes a channel
1712
1787
{
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 ) ;
1715
1800
// 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 ) ;
1717
1802
}
1718
1803
// TODO: Test NetworkUpdate::NodeFailure, which is not implemented yet.
1719
1804
}
@@ -2494,6 +2579,30 @@ mod tests {
2494
2579
} ) ;
2495
2580
assert ! ( result. is_err( ) ) ;
2496
2581
}
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
+ }
2497
2606
}
2498
2607
2499
2608
#[ cfg( all( test, feature = "unstable" ) ) ]
0 commit comments