@@ -286,9 +286,25 @@ impl ChannelMonitor {
286
286
}
287
287
}
288
288
}
289
- // TODO: Prune payment_preimages no longer needed by the revocation (just have to check
290
- // that non-revoked remote commitment tx(n) do not need it, and our latest local commitment
291
- // tx does not need it.
289
+
290
+ let local_signed_commitment_tx = & self . current_local_signed_commitment_tx ;
291
+ let remote_claimable_outpoints = & self . remote_claimable_outpoints ;
292
+ self . payment_preimages . retain ( |& k, _| {
293
+ for & ( ref htlc, _s1, _s2) in & local_signed_commitment_tx. as_ref ( ) . expect ( "Channel needs at least an initial commitment tx !" ) . htlc_outputs {
294
+ if k == htlc. payment_hash {
295
+ return true
296
+ }
297
+ }
298
+ for ( _tx, htlcs) in remote_claimable_outpoints {
299
+ for htlc in htlcs {
300
+ if k == htlc. payment_hash {
301
+ return true
302
+ }
303
+ }
304
+ }
305
+ false
306
+ } ) ;
307
+
292
308
Ok ( ( ) )
293
309
}
294
310
@@ -796,9 +812,15 @@ impl ChannelMonitor {
796
812
mod tests {
797
813
use bitcoin:: util:: misc:: hex_bytes;
798
814
use bitcoin:: blockdata:: script:: Script ;
815
+ use bitcoin:: util:: hash:: { Hash160 , Sha256dHash } ;
816
+ use bitcoin:: blockdata:: transaction:: Transaction ;
799
817
use ln:: channelmonitor:: ChannelMonitor ;
818
+ use ln:: channelmonitor:: LocalSignedTx ;
819
+ use ln:: chan_utils:: HTLCOutputInCommitment ;
800
820
use secp256k1:: key:: { SecretKey , PublicKey } ;
801
- use secp256k1:: Secp256k1 ;
821
+ use secp256k1:: { Secp256k1 , Signature } ;
822
+ use rand:: { thread_rng, Rng } ;
823
+ use std:: collections:: HashMap ;
802
824
803
825
#[ test]
804
826
fn test_per_commitment_storage ( ) {
@@ -1154,5 +1176,146 @@ mod tests {
1154
1176
}
1155
1177
}
1156
1178
1179
+ macro_rules! gen_local_tx {
1180
+ ( $hex : expr, $monitor : expr, $htlcs : expr, $rng : expr, $preimage : expr, $hash : expr) => {
1181
+ {
1182
+
1183
+ let mut htlcs = Vec :: new( ) ;
1184
+
1185
+ for _i in 0 ..$htlcs {
1186
+ $rng. fill_bytes( & mut $preimage) ;
1187
+ $hash[ 0 ..20 ] . clone_from_slice( & Hash160 :: from_data( & $preimage) [ 0 ..20 ] ) ;
1188
+ $monitor. provide_payment_preimage( & $hash, & $preimage) ;
1189
+ htlcs. push( ( HTLCOutputInCommitment {
1190
+ offered : true ,
1191
+ amount_msat : 0 ,
1192
+ cltv_expiry : 0 ,
1193
+ payment_hash : $hash. clone( ) ,
1194
+ transaction_output_index : 0 ,
1195
+ } , Signature :: from_der( & Secp256k1 :: new( ) , $hex) . unwrap( ) ,
1196
+ Signature :: from_der( & Secp256k1 :: new( ) , $hex) . unwrap( ) ) )
1197
+ }
1198
+
1199
+ Some ( LocalSignedTx {
1200
+ txid: Sha256dHash :: from_data( & [ ] ) ,
1201
+ tx: Transaction {
1202
+ version: 0 ,
1203
+ lock_time: 0 ,
1204
+ input: Vec :: new( ) ,
1205
+ output: Vec :: new( ) ,
1206
+ } ,
1207
+ revocation_key: PublicKey :: new( ) ,
1208
+ a_htlc_key: PublicKey :: new( ) ,
1209
+ b_htlc_key: PublicKey :: new( ) ,
1210
+ delayed_payment_key: PublicKey :: new( ) ,
1211
+ feerate_per_kw: 0 ,
1212
+ htlc_outputs: htlcs,
1213
+ } )
1214
+ }
1215
+ }
1216
+ }
1217
+
1218
+ macro_rules! gen_remote_htlcs {
1219
+ ( $monitor : expr, $tx : expr, $htlcs : expr, $rng : expr, $preimage : expr, $hash: expr) => {
1220
+ {
1221
+ let mut remote_outpoints = HashMap :: new( ) ;
1222
+
1223
+ for i in 0 ..$tx {
1224
+
1225
+ let tx_zero = Transaction {
1226
+ version : 0 ,
1227
+ lock_time : i,
1228
+ input : Vec :: new( ) ,
1229
+ output: Vec :: new( ) ,
1230
+ } ;
1231
+
1232
+ let mut htlcs = Vec :: new( ) ;
1233
+
1234
+ for _i in 0 ..$htlcs {
1235
+ $rng. fill_bytes( & mut $preimage) ;
1236
+ $hash[ 0 ..20 ] . clone_from_slice( & Hash160 :: from_data( & $preimage) [ 0 ..20 ] ) ;
1237
+ $monitor. provide_payment_preimage( & $hash, & $preimage) ;
1238
+ htlcs. push( HTLCOutputInCommitment {
1239
+ offered : true ,
1240
+ amount_msat : 0 ,
1241
+ cltv_expiry : 0 ,
1242
+ payment_hash : $hash. clone( ) ,
1243
+ transaction_output_index : 0 ,
1244
+ } ) ;
1245
+ }
1246
+ remote_outpoints. insert( tx_zero. txid( ) , htlcs) ;
1247
+ }
1248
+ remote_outpoints
1249
+ }
1250
+ }
1251
+ }
1252
+
1253
+ #[ test]
1254
+ fn test_prune_preimages ( ) {
1255
+
1256
+ let mut monitor : ChannelMonitor ;
1257
+ let secp_ctx = Secp256k1 :: new ( ) ;
1258
+ let mut preimage : [ u8 ; 32 ] = [ 0 ; 32 ] ;
1259
+ let mut hash : [ u8 ; 32 ] = [ 0 ; 32 ] ;
1260
+ let mut rng = thread_rng ( ) ;
1261
+
1262
+ {
1263
+ monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1264
+
1265
+ for _i in 0 ..30 {
1266
+ rng. fill_bytes ( & mut preimage) ;
1267
+ hash[ 0 ..20 ] . clone_from_slice ( & Hash160 :: from_data ( & preimage) [ 0 ..20 ] ) ;
1268
+ monitor. provide_payment_preimage ( & hash, & preimage) ;
1269
+ }
1270
+ monitor. current_local_signed_commitment_tx = gen_local_tx ! ( & hex_bytes( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap( ) [ ..] , monitor, 10 , rng, preimage, hash) ;
1271
+ monitor. remote_claimable_outpoints = gen_remote_htlcs ! ( monitor, 1 , 10 , rng, preimage, hash) ;
1272
+ monitor. provide_secret ( 0 , [ 0 ; 32 ] , None ) ;
1273
+ assert_eq ! ( monitor. payment_preimages. len( ) , 20 ) ;
1274
+ }
1275
+
1276
+
1277
+ {
1278
+ monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1279
+
1280
+ for _i in 0 ..30 {
1281
+ rng. fill_bytes ( & mut preimage) ;
1282
+ hash[ 0 ..20 ] . clone_from_slice ( & Hash160 :: from_data ( & preimage) [ 0 ..20 ] ) ;
1283
+ monitor. provide_payment_preimage ( & hash, & preimage) ;
1284
+ }
1285
+ monitor. current_local_signed_commitment_tx = gen_local_tx ! ( & hex_bytes( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap( ) [ ..] , monitor, 0 , rng, preimage, hash) ;
1286
+ monitor. remote_claimable_outpoints = gen_remote_htlcs ! ( monitor, 0 , 0 , rng, preimage, hash) ;
1287
+ monitor. provide_secret ( 0 , [ 0 ; 32 ] , None ) ;
1288
+ assert_eq ! ( monitor. payment_preimages. len( ) , 0 ) ;
1289
+ }
1290
+
1291
+ {
1292
+ monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1293
+
1294
+ for _i in 0 ..30 {
1295
+ rng. fill_bytes ( & mut preimage) ;
1296
+ hash[ 0 ..20 ] . clone_from_slice ( & Hash160 :: from_data ( & preimage) [ 0 ..20 ] ) ;
1297
+ monitor. provide_payment_preimage ( & hash, & preimage) ;
1298
+ }
1299
+ monitor. current_local_signed_commitment_tx = gen_local_tx ! ( & hex_bytes( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap( ) [ ..] , monitor, 0 , rng, preimage, hash) ;
1300
+ monitor. remote_claimable_outpoints = gen_remote_htlcs ! ( monitor, 5 , 5 , rng, preimage, hash) ;
1301
+ monitor. provide_secret ( 0 , [ 0 ; 32 ] , None ) ;
1302
+ assert_eq ! ( monitor. payment_preimages. len( ) , 25 ) ;
1303
+ }
1304
+
1305
+ {
1306
+ monitor = ChannelMonitor :: new ( & SecretKey :: from_slice ( & secp_ctx, & [ 42 ; 32 ] ) . unwrap ( ) , & PublicKey :: new ( ) , & SecretKey :: from_slice ( & secp_ctx, & [ 43 ; 32 ] ) . unwrap ( ) , 0 , Script :: new ( ) ) ;
1307
+
1308
+ for _i in 0 ..30 {
1309
+ rng. fill_bytes ( & mut preimage) ;
1310
+ hash[ 0 ..20 ] . clone_from_slice ( & Hash160 :: from_data ( & preimage) [ 0 ..20 ] ) ;
1311
+ monitor. provide_payment_preimage ( & hash, & preimage) ;
1312
+ }
1313
+ monitor. current_local_signed_commitment_tx = gen_local_tx ! ( & hex_bytes( "3045022100fa86fa9a36a8cd6a7bb8f06a541787d51371d067951a9461d5404de6b928782e02201c8b7c334c10aed8976a3a465be9a28abff4cb23acbf00022295b378ce1fa3cd" ) . unwrap( ) [ ..] , monitor, 25 , rng, preimage, hash) ;
1314
+ monitor. remote_claimable_outpoints = gen_remote_htlcs ! ( monitor, 0 , 0 , rng, preimage, hash) ;
1315
+ monitor. provide_secret ( 0 , [ 0 ; 32 ] , None ) ;
1316
+ assert_eq ! ( monitor. payment_preimages. len( ) , 25 ) ;
1317
+ }
1318
+ }
1319
+
1157
1320
// Further testing is done in the ChannelManager integration tests.
1158
1321
}
0 commit comments