9
9
10
10
//! Further functional tests which test blockchain reorganizations.
11
11
12
- use chain:: channelmonitor:: ANTI_REORG_DELAY ;
12
+ use chain:: channelmonitor:: { ANTI_REORG_DELAY , ChannelMonitor } ;
13
+ use chain:: Watch ;
14
+ use ln:: channelmanager:: { ChannelManager , ChannelManagerReadArgs } ;
13
15
use ln:: features:: InitFeatures ;
14
16
use ln:: msgs:: { ChannelMessageHandler , ErrorAction , HTLCFailChannelUpdate } ;
17
+ use util:: config:: UserConfig ;
18
+ use util:: enforcing_trait_impls:: EnforcingSigner ;
15
19
use util:: events:: { Event , EventsProvider , MessageSendEvent , MessageSendEventsProvider } ;
20
+ use util:: test_utils;
21
+ use util:: ser:: { ReadableArgs , Writeable } ;
16
22
17
23
use bitcoin:: blockdata:: block:: { Block , BlockHeader } ;
24
+ use bitcoin:: hash_types:: BlockHash ;
18
25
19
- use std:: default :: Default ;
26
+ use std:: collections :: HashMap ;
20
27
use std:: mem;
21
28
22
29
use ln:: functional_test_utils:: * ;
@@ -182,14 +189,18 @@ fn test_onchain_htlc_timeout_delay_remote_commitment() {
182
189
do_test_onchain_htlc_reorg ( false , false ) ;
183
190
}
184
191
185
- #[ test]
186
- fn test_unconf_chan ( ) {
187
- // After creating a chan between nodes, we disconnect all blocks previously seen to force a channel close on nodes[0] side
192
+ fn do_test_unconf_chan ( reload_node : bool , reorg_after_reload : bool ) {
193
+ // After creating a chan between nodes, we disconnect all blocks previously seen to force a
194
+ // channel close on nodes[0] side. We also use this to provide very basic testing of logic
195
+ // around freeing background events which store monitor updates during block_[dis]connected.
188
196
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
189
197
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
190
198
let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
191
- let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
192
- create_announced_chan_between_nodes ( & nodes, 0 , 1 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
199
+ let persister: test_utils:: TestPersister ;
200
+ let new_chain_monitor: test_utils:: TestChainMonitor ;
201
+ let nodes_0_deserialized: ChannelManager < EnforcingSigner , & test_utils:: TestChainMonitor , & test_utils:: TestBroadcaster , & test_utils:: TestKeysInterface , & test_utils:: TestFeeEstimator , & test_utils:: TestLogger > ;
202
+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
203
+ let chan_id = create_announced_chan_between_nodes ( & nodes, 0 , 1 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) . 2 ;
193
204
194
205
let channel_state = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) ;
195
206
assert_eq ! ( channel_state. by_id. len( ) , 1 ) ;
@@ -203,15 +214,83 @@ fn test_unconf_chan() {
203
214
header = BlockHeader { version : 0x20000000 , prev_blockhash : header. block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
204
215
headers. push ( header. clone ( ) ) ;
205
216
}
206
- while !headers. is_empty ( ) {
207
- nodes[ 0 ] . node . block_disconnected ( & headers. pop ( ) . unwrap ( ) ) ;
217
+ if !reorg_after_reload {
218
+ while !headers. is_empty ( ) {
219
+ nodes[ 0 ] . node . block_disconnected ( & headers. pop ( ) . unwrap ( ) ) ;
220
+ }
221
+ check_closed_broadcast ! ( nodes[ 0 ] , false ) ;
222
+ {
223
+ let channel_state = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) ;
224
+ assert_eq ! ( channel_state. by_id. len( ) , 0 ) ;
225
+ assert_eq ! ( channel_state. short_to_id. len( ) , 0 ) ;
226
+ }
208
227
}
209
- check_closed_broadcast ! ( nodes[ 0 ] , false ) ;
228
+
229
+ if reload_node {
230
+ // Since we currently have a background event pending, it's good to test that we survive a
231
+ // serialization roundtrip. Further, this tests the somewhat awkward edge-case of dropping
232
+ // the Channel object from the ChannelManager, but still having a monitor event pending for
233
+ // it when we go to deserialize, and then use the ChannelManager.
234
+ let nodes_0_serialized = nodes[ 0 ] . node . encode ( ) ;
235
+ let mut chan_0_monitor_serialized = test_utils:: TestVecWriter ( Vec :: new ( ) ) ;
236
+ nodes[ 0 ] . chain_monitor . chain_monitor . monitors . read ( ) . unwrap ( ) . iter ( ) . next ( ) . unwrap ( ) . 1 . write ( & mut chan_0_monitor_serialized) . unwrap ( ) ;
237
+
238
+ persister = test_utils:: TestPersister :: new ( ) ;
239
+ let keys_manager = & chanmon_cfgs[ 0 ] . keys_manager ;
240
+ new_chain_monitor = test_utils:: TestChainMonitor :: new ( Some ( nodes[ 0 ] . chain_source ) , nodes[ 0 ] . tx_broadcaster . clone ( ) , nodes[ 0 ] . logger , node_cfgs[ 0 ] . fee_estimator , & persister, keys_manager) ;
241
+ nodes[ 0 ] . chain_monitor = & new_chain_monitor;
242
+ let mut chan_0_monitor_read = & chan_0_monitor_serialized. 0 [ ..] ;
243
+ let ( _, mut chan_0_monitor) = <( Option < BlockHash > , ChannelMonitor < EnforcingSigner > ) >:: read (
244
+ & mut chan_0_monitor_read, keys_manager) . unwrap ( ) ;
245
+ assert ! ( chan_0_monitor_read. is_empty( ) ) ;
246
+
247
+ let mut nodes_0_read = & nodes_0_serialized[ ..] ;
248
+ let config = UserConfig :: default ( ) ;
249
+ nodes_0_deserialized = {
250
+ let mut channel_monitors = HashMap :: new ( ) ;
251
+ channel_monitors. insert ( chan_0_monitor. get_funding_txo ( ) . 0 , & mut chan_0_monitor) ;
252
+ <( Option < BlockHash > , ChannelManager < EnforcingSigner , & test_utils:: TestChainMonitor , & test_utils:: TestBroadcaster ,
253
+ & test_utils:: TestKeysInterface , & test_utils:: TestFeeEstimator , & test_utils:: TestLogger > ) >:: read (
254
+ & mut nodes_0_read, ChannelManagerReadArgs {
255
+ default_config : config,
256
+ keys_manager,
257
+ fee_estimator : node_cfgs[ 0 ] . fee_estimator ,
258
+ chain_monitor : nodes[ 0 ] . chain_monitor ,
259
+ tx_broadcaster : nodes[ 0 ] . tx_broadcaster . clone ( ) ,
260
+ logger : nodes[ 0 ] . logger ,
261
+ channel_monitors,
262
+ } ) . unwrap ( ) . 1
263
+ } ;
264
+ nodes[ 0 ] . node = & nodes_0_deserialized;
265
+ assert ! ( nodes_0_read. is_empty( ) ) ;
266
+
267
+ nodes[ 0 ] . chain_monitor . watch_channel ( chan_0_monitor. get_funding_txo ( ) . 0 . clone ( ) , chan_0_monitor) . unwrap ( ) ;
268
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
269
+ }
270
+
271
+ if reorg_after_reload {
272
+ while !headers. is_empty ( ) {
273
+ nodes[ 0 ] . node . block_disconnected ( & headers. pop ( ) . unwrap ( ) ) ;
274
+ }
275
+ check_closed_broadcast ! ( nodes[ 0 ] , false ) ;
276
+ {
277
+ let channel_state = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) ;
278
+ assert_eq ! ( channel_state. by_id. len( ) , 0 ) ;
279
+ assert_eq ! ( channel_state. short_to_id. len( ) , 0 ) ;
280
+ }
281
+ }
282
+
283
+ * nodes[ 0 ] . chain_monitor . expect_channel_force_closed . lock ( ) . unwrap ( ) = Some ( ( chan_id, true ) ) ;
210
284
nodes[ 0 ] . node . test_process_background_events ( ) ; // Required to free the pending background monitor update
211
285
check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
212
- let channel_state = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) ;
213
- assert_eq ! ( channel_state. by_id. len( ) , 0 ) ;
214
- assert_eq ! ( channel_state. short_to_id. len( ) , 0 ) ;
286
+ }
287
+
288
+ #[ test]
289
+ fn test_unconf_chan ( ) {
290
+ do_test_unconf_chan ( true , true ) ;
291
+ do_test_unconf_chan ( false , true ) ;
292
+ do_test_unconf_chan ( true , false ) ;
293
+ do_test_unconf_chan ( false , false ) ;
215
294
}
216
295
217
296
#[ test]
0 commit comments