@@ -295,28 +295,36 @@ impl ChannelMonitor {
295
295
}
296
296
}
297
297
298
- let mut waste_hash_state : Vec < [ u8 ; 32 ] > = Vec :: new ( ) ;
299
- {
300
- let local_signed_commitment_tx = & self . current_local_signed_commitment_tx ;
301
- let remote_hash_commitment_number = & self . remote_hash_commitment_number ;
298
+ if !self . payment_preimages . is_empty ( ) {
299
+ let local_signed_commitment_tx = self . current_local_signed_commitment_tx . as_ref ( ) . expect ( "Channel needs at least an initial commitment tx !" ) ;
300
+ let prev_local_signed_commitment_tx = self . prev_local_signed_commitment_tx . as_ref ( ) ;
302
301
let min_idx = self . get_min_seen_secret ( ) ;
302
+ let remote_hash_commitment_number = & mut self . remote_hash_commitment_number ;
303
+
303
304
self . payment_preimages . retain ( |& k, _| {
304
- for & ( ref htlc, _s1, _s2) in & local_signed_commitment_tx. as_ref ( ) . expect ( "Channel needs at least an initial commitment tx !" ) . htlc_outputs {
305
+ for & ( ref htlc, _, _) in & local_signed_commitment_tx. htlc_outputs {
306
+ if k == htlc. payment_hash {
307
+ return true
308
+ }
309
+ }
310
+ if let Some ( prev_local_commitment_tx) = prev_local_signed_commitment_tx {
311
+ for & ( ref htlc, _, _) in prev_local_commitment_tx. htlc_outputs . iter ( ) {
305
312
if k == htlc. payment_hash {
306
313
return true
307
314
}
308
315
}
309
- if let Some ( cn ) = remote_hash_commitment_number . get ( & k ) {
310
- if * cn < min_idx {
311
- return true
312
- }
316
+ }
317
+ let contains = if let Some ( cn ) = remote_hash_commitment_number . get ( & k ) {
318
+ if * cn < min_idx {
319
+ return true
313
320
}
314
- waste_hash_state. push ( k) ;
315
- false
316
- } ) ;
317
- }
318
- for h in waste_hash_state {
319
- self . remote_hash_commitment_number . remove ( & h) ;
321
+ true
322
+ } else { false } ;
323
+ if contains {
324
+ remote_hash_commitment_number. remove ( & k) ;
325
+ }
326
+ false
327
+ } ) ;
320
328
}
321
329
322
330
Ok ( ( ) )
@@ -830,15 +838,14 @@ impl ChannelMonitor {
830
838
mod tests {
831
839
use bitcoin:: util:: misc:: hex_bytes;
832
840
use bitcoin:: blockdata:: script:: Script ;
833
- use bitcoin:: util:: hash:: { Hash160 , Sha256dHash } ;
834
841
use bitcoin:: blockdata:: transaction:: Transaction ;
842
+ use crypto:: digest:: Digest ;
835
843
use ln:: channelmonitor:: ChannelMonitor ;
836
- use ln:: channelmonitor :: LocalSignedTx ;
837
- use ln :: chan_utils :: HTLCOutputInCommitment ;
844
+ use ln:: chan_utils :: { HTLCOutputInCommitment , TxCreationKeys } ;
845
+ use util :: sha2 :: Sha256 ;
838
846
use secp256k1:: key:: { SecretKey , PublicKey } ;
839
847
use secp256k1:: { Secp256k1 , Signature } ;
840
848
use rand:: { thread_rng, Rng } ;
841
- use std:: collections:: HashMap ;
842
849
843
850
#[ test]
844
851
fn test_per_commitment_storage ( ) {
@@ -1194,162 +1201,118 @@ mod tests {
1194
1201
}
1195
1202
}
1196
1203
1197
- macro_rules! gen_local_tx {
1198
- ( $hex : expr, $monitor : expr, $htlcs : expr, $rng : expr, $preimage : expr, $hash : expr) => {
1199
- {
1200
-
1201
- let mut htlcs = Vec :: new( ) ;
1202
-
1203
- for _i in 0 ..$htlcs {
1204
- $rng. fill_bytes( & mut $preimage) ;
1205
- $hash[ 0 ..20 ] . clone_from_slice( & Hash160 :: from_data( & $preimage) [ 0 ..20 ] ) ;
1206
- $monitor. provide_payment_preimage( & $hash, & $preimage) ;
1207
- htlcs. push( ( HTLCOutputInCommitment {
1208
- offered : true ,
1209
- amount_msat : 0 ,
1210
- cltv_expiry : 0 ,
1211
- payment_hash : $hash. clone( ) ,
1212
- transaction_output_index : 0 ,
1213
- } , Signature :: from_der( & Secp256k1 :: new( ) , $hex) . unwrap( ) ,
1214
- Signature :: from_der( & Secp256k1 :: new( ) , $hex) . unwrap( ) ) )
1215
- }
1204
+ #[ test]
1205
+ fn test_prune_preimages ( ) {
1206
+ let secp_ctx = Secp256k1 :: new ( ) ;
1207
+ let dummy_sig = Signature :: from_der ( & secp_ctx, & hex_bytes ( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap ( ) [ ..] ) . unwrap ( ) ;
1216
1208
1217
- Some ( LocalSignedTx {
1218
- txid: Sha256dHash :: from_data( & [ ] ) ,
1219
- tx: Transaction {
1220
- version: 0 ,
1221
- lock_time: 0 ,
1222
- input: Vec :: new( ) ,
1223
- output: Vec :: new( ) ,
1224
- } ,
1209
+ macro_rules! dummy_keys {
1210
+ ( ) => {
1211
+ TxCreationKeys {
1212
+ per_commitment_point: PublicKey :: new( ) ,
1225
1213
revocation_key: PublicKey :: new( ) ,
1226
1214
a_htlc_key: PublicKey :: new( ) ,
1227
1215
b_htlc_key: PublicKey :: new( ) ,
1228
- delayed_payment_key: PublicKey :: new( ) ,
1229
- feerate_per_kw: 0 ,
1230
- htlc_outputs: htlcs,
1231
- } )
1216
+ a_delayed_payment_key: PublicKey :: new( ) ,
1217
+ b_payment_key: PublicKey :: new( ) ,
1218
+ }
1232
1219
}
1233
1220
}
1234
- }
1221
+ let dummy_tx = Transaction { version : 0 , lock_time : 0 , input : Vec :: new ( ) , output : Vec :: new ( ) } ;
1235
1222
1236
- macro_rules! gen_remote_outpoints {
1237
- ( $monitor : expr , $tx : expr , $htlcs : expr , $rng : expr , $preimage : expr , $hash : expr , $number : expr ) => {
1238
- {
1239
- let mut commitment_number = $number ;
1240
-
1241
- for i in 0 ..$tx {
1242
-
1243
- let tx_zero = Transaction {
1244
- version : 0 ,
1245
- lock_time : i ,
1246
- input : Vec :: new ( ) ,
1247
- output : Vec :: new ( ) ,
1248
- } ;
1223
+ let mut preimages = Vec :: new ( ) ;
1224
+ {
1225
+ let mut rng = thread_rng ( ) ;
1226
+ for _ in 0 .. 20 {
1227
+ let mut preimage = [ 0 ; 32 ] ;
1228
+ rng . fill_bytes ( & mut preimage ) ;
1229
+ let mut sha = Sha256 :: new ( ) ;
1230
+ sha . input ( & preimage ) ;
1231
+ let mut hash = [ 0 ; 32 ] ;
1232
+ sha . result ( & mut hash ) ;
1233
+ preimages . push ( ( preimage , hash ) ) ;
1234
+ }
1235
+ }
1249
1236
1250
- let mut htlcs = Vec :: new( ) ;
1251
-
1252
- for _i in 0 ..$htlcs {
1253
- $rng. fill_bytes( & mut $preimage) ;
1254
- $hash[ 0 ..20 ] . clone_from_slice( & Hash160 :: from_data( & $preimage) [ 0 ..20 ] ) ;
1255
- $monitor. provide_payment_preimage( & $hash, & $preimage) ;
1256
- htlcs. push( HTLCOutputInCommitment {
1257
- offered : true ,
1258
- amount_msat : 0 ,
1259
- cltv_expiry : 0 ,
1260
- payment_hash : $hash. clone( ) ,
1261
- transaction_output_index : 0 ,
1237
+ macro_rules! preimages_slice_to_htlc_outputs {
1238
+ ( $preimages_slice: expr) => {
1239
+ {
1240
+ let mut res = Vec :: new( ) ;
1241
+ for ( idx, preimage) in $preimages_slice. iter( ) . enumerate( ) {
1242
+ res. push( HTLCOutputInCommitment {
1243
+ offered: true ,
1244
+ amount_msat: 0 ,
1245
+ cltv_expiry: 0 ,
1246
+ payment_hash: preimage. 1 . clone( ) ,
1247
+ transaction_output_index: idx as u32 ,
1262
1248
} ) ;
1263
1249
}
1264
- commitment_number -= 1 ;
1265
- $monitor. provide_latest_remote_commitment_tx_info( & tx_zero, htlcs, commitment_number) ;
1250
+ res
1266
1251
}
1267
1252
}
1268
1253
}
1269
- }
1270
-
1271
- #[ test]
1272
- fn test_prune_preimages ( ) {
1273
-
1274
- let mut monitor: ChannelMonitor ;
1275
- let mut secrets: Vec < [ u8 ; 32 ] > = Vec :: new ( ) ;
1276
- let secp_ctx = Secp256k1 :: new ( ) ;
1277
- let mut preimage: [ u8 ; 32 ] = [ 0 ; 32 ] ;
1278
- let mut hash: [ u8 ; 32 ] = [ 0 ; 32 ] ;
1279
- let mut rng = thread_rng ( ) ;
1280
-
1281
- {
1282
- // insert 30 random hash, 10 from local, 10 from remote, prune 30/50
1283
- monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1284
-
1285
- for _i in 0 ..30 {
1286
- rng. fill_bytes ( & mut preimage) ;
1287
- hash[ 0 ..20 ] . clone_from_slice ( & Hash160 :: from_data ( & preimage) [ 0 ..20 ] ) ;
1288
- monitor. provide_payment_preimage ( & hash, & preimage) ;
1254
+ macro_rules! preimages_to_local_htlcs {
1255
+ ( $preimages_slice: expr) => {
1256
+ {
1257
+ let mut inp = preimages_slice_to_htlc_outputs!( $preimages_slice) ;
1258
+ let res: Vec <_> = inp. drain( ..) . map( |e| { ( e, dummy_sig. clone( ) , dummy_sig. clone( ) ) } ) . collect( ) ;
1259
+ res
1260
+ }
1289
1261
}
1290
- monitor. current_local_signed_commitment_tx = gen_local_tx ! ( & hex_bytes( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap( ) [ ..] , monitor, 10 , rng, preimage, hash) ;
1291
- gen_remote_outpoints ! ( monitor, 1 , 10 , rng, preimage, hash, 281474976710654 ) ;
1292
- secrets. clear ( ) ;
1293
- secrets. push ( [ 0 ; 32 ] ) ;
1294
- secrets. last_mut ( ) . unwrap ( ) [ 0 ..32 ] . clone_from_slice ( & hex_bytes ( "7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc" ) . unwrap ( ) ) ;
1295
- monitor. provide_secret ( 281474976710655 , secrets. last ( ) . unwrap ( ) . clone ( ) , None ) ;
1296
- assert_eq ! ( monitor. payment_preimages. len( ) , 20 ) ;
1297
1262
}
1298
1263
1299
-
1300
- {
1301
- // insert 30 random hash, prune 30/30
1302
- monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1303
-
1304
- for _i in 0 ..30 {
1305
- rng. fill_bytes ( & mut preimage) ;
1306
- hash[ 0 ..20 ] . clone_from_slice ( & Hash160 :: from_data ( & preimage) [ 0 ..20 ] ) ;
1307
- monitor. provide_payment_preimage ( & hash, & preimage) ;
1264
+ macro_rules! test_preimages_exist {
1265
+ ( $preimages_slice: expr, $monitor: expr) => {
1266
+ for preimage in $preimages_slice {
1267
+ assert!( $monitor. payment_preimages. contains_key( & preimage. 1 ) ) ;
1268
+ }
1308
1269
}
1309
- monitor. current_local_signed_commitment_tx = gen_local_tx ! ( & hex_bytes( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap( ) [ ..] , monitor, 0 , rng, preimage, hash) ;
1310
- gen_remote_outpoints ! ( monitor, 0 , 0 , rng, preimage, hash, 281474976710655 ) ;
1311
- secrets. clear ( ) ;
1312
- secrets. push ( [ 0 ; 32 ] ) ;
1313
- secrets. last_mut ( ) . unwrap ( ) [ 0 ..32 ] . clone_from_slice ( & hex_bytes ( "7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc" ) . unwrap ( ) ) ;
1314
- monitor. provide_secret ( 281474976710655 , secrets. last ( ) . unwrap ( ) . clone ( ) , None ) ;
1315
- assert_eq ! ( monitor. payment_preimages. len( ) , 0 ) ;
1316
1270
}
1317
1271
1318
- {
1319
- // insert 30 random hash, 25 on 5 remotes, prune 30/55
1320
- monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1321
-
1322
- for _i in 0 ..30 {
1323
- rng. fill_bytes ( & mut preimage) ;
1324
- hash[ 0 ..20 ] . clone_from_slice ( & Hash160 :: from_data ( & preimage) [ 0 ..20 ] ) ;
1325
- monitor. provide_payment_preimage ( & hash, & preimage) ;
1326
- }
1327
- monitor. current_local_signed_commitment_tx = gen_local_tx ! ( & hex_bytes( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap( ) [ ..] , monitor, 0 , rng, preimage, hash) ;
1328
- gen_remote_outpoints ! ( monitor, 5 , 5 , rng, preimage, hash, 281474976710654 ) ;
1329
- secrets. clear ( ) ;
1330
- secrets. push ( [ 0 ; 32 ] ) ;
1331
- secrets. last_mut ( ) . unwrap ( ) [ 0 ..32 ] . clone_from_slice ( & hex_bytes ( "7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc" ) . unwrap ( ) ) ;
1332
- monitor. provide_secret ( 281474976710655 , secrets. last ( ) . unwrap ( ) . clone ( ) , None ) ;
1333
- assert_eq ! ( monitor. payment_preimages. len( ) , 25 ) ;
1272
+ // Prune with one old state and a local commitment tx holding a few overlaps with the
1273
+ // old state.
1274
+ let mut monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1275
+ monitor. set_their_to_self_delay ( 10 ) ;
1276
+
1277
+ monitor. provide_latest_local_commitment_tx_info ( dummy_tx. clone ( ) , dummy_keys ! ( ) , 0 , preimages_to_local_htlcs ! ( preimages[ 0 ..10 ] ) ) ;
1278
+ monitor. provide_latest_remote_commitment_tx_info ( & dummy_tx, preimages_slice_to_htlc_outputs ! ( preimages[ 5 ..15 ] ) , 281474976710655 ) ;
1279
+ monitor. provide_latest_remote_commitment_tx_info ( & dummy_tx, preimages_slice_to_htlc_outputs ! ( preimages[ 15 ..20 ] ) , 281474976710654 ) ;
1280
+ monitor. provide_latest_remote_commitment_tx_info ( & dummy_tx, preimages_slice_to_htlc_outputs ! ( preimages[ 17 ..20 ] ) , 281474976710653 ) ;
1281
+ monitor. provide_latest_remote_commitment_tx_info ( & dummy_tx, preimages_slice_to_htlc_outputs ! ( preimages[ 18 ..20 ] ) , 281474976710652 ) ;
1282
+ for & ( ref preimage, ref hash) in preimages. iter ( ) {
1283
+ monitor. provide_payment_preimage ( hash, preimage) ;
1334
1284
}
1335
1285
1336
- {
1337
- // insert 30 random hash, 25 from local, prune 30/55
1338
- monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1339
-
1340
- for _i in 0 ..30 {
1341
- rng. fill_bytes ( & mut preimage) ;
1342
- hash[ 0 ..20 ] . clone_from_slice ( & Hash160 :: from_data ( & preimage) [ 0 ..20 ] ) ;
1343
- monitor. provide_payment_preimage ( & hash, & preimage) ;
1344
- }
1345
- monitor. current_local_signed_commitment_tx = gen_local_tx ! ( & hex_bytes( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap( ) [ ..] , monitor, 25 , rng, preimage, hash) ;
1346
- gen_remote_outpoints ! ( monitor, 0 , 0 , rng, preimage, hash, 281474976710655 ) ;
1347
- secrets. clear ( ) ;
1348
- secrets. push ( [ 0 ; 32 ] ) ;
1349
- secrets. last_mut ( ) . unwrap ( ) [ 0 ..32 ] . clone_from_slice ( & hex_bytes ( "7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc" ) . unwrap ( ) ) ;
1350
- monitor. provide_secret ( 281474976710655 , secrets. last ( ) . unwrap ( ) . clone ( ) , None ) ;
1351
- assert_eq ! ( monitor. payment_preimages. len( ) , 25 ) ;
1352
- }
1286
+ // Now provide a secret, pruning preimages 10-15
1287
+ let mut secret = [ 0 ; 32 ] ;
1288
+ secret[ 0 ..32 ] . clone_from_slice ( & hex_bytes ( "7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc" ) . unwrap ( ) ) ;
1289
+ monitor. provide_secret ( 281474976710655 , secret. clone ( ) , None ) . unwrap ( ) ;
1290
+ assert_eq ! ( monitor. payment_preimages. len( ) , 15 ) ;
1291
+ test_preimages_exist ! ( & preimages[ 0 ..10 ] , monitor) ;
1292
+ test_preimages_exist ! ( & preimages[ 15 ..20 ] , monitor) ;
1293
+
1294
+ // Now provide a further secret, pruning preimages 15-17
1295
+ secret[ 0 ..32 ] . clone_from_slice ( & hex_bytes ( "c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964" ) . unwrap ( ) ) ;
1296
+ monitor. provide_secret ( 281474976710654 , secret. clone ( ) , None ) . unwrap ( ) ;
1297
+ assert_eq ! ( monitor. payment_preimages. len( ) , 13 ) ;
1298
+ test_preimages_exist ! ( & preimages[ 0 ..10 ] , monitor) ;
1299
+ test_preimages_exist ! ( & preimages[ 17 ..20 ] , monitor) ;
1300
+
1301
+ // Now update local commitment tx info, pruning only element 18 as we still care about the
1302
+ // previous commitment tx's preimages too
1303
+ monitor. provide_latest_local_commitment_tx_info ( dummy_tx. clone ( ) , dummy_keys ! ( ) , 0 , preimages_to_local_htlcs ! ( preimages[ 0 ..5 ] ) ) ;
1304
+ secret[ 0 ..32 ] . clone_from_slice ( & hex_bytes ( "2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8" ) . unwrap ( ) ) ;
1305
+ monitor. provide_secret ( 281474976710653 , secret. clone ( ) , None ) . unwrap ( ) ;
1306
+ assert_eq ! ( monitor. payment_preimages. len( ) , 12 ) ;
1307
+ test_preimages_exist ! ( & preimages[ 0 ..10 ] , monitor) ;
1308
+ test_preimages_exist ! ( & preimages[ 18 ..20 ] , monitor) ;
1309
+
1310
+ // But if we do it again, we'll prune 5-10
1311
+ monitor. provide_latest_local_commitment_tx_info ( dummy_tx. clone ( ) , dummy_keys ! ( ) , 0 , preimages_to_local_htlcs ! ( preimages[ 0 ..3 ] ) ) ;
1312
+ secret[ 0 ..32 ] . clone_from_slice ( & hex_bytes ( "27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116" ) . unwrap ( ) ) ;
1313
+ monitor. provide_secret ( 281474976710652 , secret. clone ( ) , None ) . unwrap ( ) ;
1314
+ assert_eq ! ( monitor. payment_preimages. len( ) , 5 ) ;
1315
+ test_preimages_exist ! ( & preimages[ 0 ..5 ] , monitor) ;
1353
1316
}
1354
1317
1355
1318
// Further testing is done in the ChannelManager integration tests.
0 commit comments