@@ -763,6 +763,7 @@ pub(crate) struct ChannelMonitorImpl<Signer: WriteableEcdsaChannelSigner> {
763
763
channel_keys_id : [ u8 ; 32 ] ,
764
764
holder_revocation_basepoint : PublicKey ,
765
765
funding_info : ( OutPoint , Script ) ,
766
+ original_funding_info : Option < ( OutPoint , Script ) > ,
766
767
current_counterparty_commitment_txid : Option < Txid > ,
767
768
prev_counterparty_commitment_txid : Option < Txid > ,
768
769
@@ -945,6 +946,13 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signe
945
946
writer. write_all ( & self . funding_info . 0 . txid [ ..] ) ?;
946
947
writer. write_all ( & self . funding_info . 0 . index . to_be_bytes ( ) ) ?;
947
948
self . funding_info . 1 . write ( writer) ?;
949
+ if let Some ( ref original_funding_info) = self . original_funding_info {
950
+ writer. write_all ( & [ 0 ; 1 ] ) ?;
951
+ original_funding_info. 0 . write ( writer) ?;
952
+ original_funding_info. 1 . write ( writer) ?;
953
+ } else {
954
+ writer. write_all ( & [ 1 ; 1 ] ) ?;
955
+ }
948
956
self . current_counterparty_commitment_txid . write ( writer) ?;
949
957
self . prev_counterparty_commitment_txid . write ( writer) ?;
950
958
@@ -1187,6 +1195,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
1187
1195
channel_keys_id,
1188
1196
holder_revocation_basepoint,
1189
1197
funding_info,
1198
+ original_funding_info : None ,
1190
1199
current_counterparty_commitment_txid : None ,
1191
1200
prev_counterparty_commitment_txid : None ,
1192
1201
@@ -1252,6 +1261,23 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
1252
1261
txid, htlc_outputs, commitment_number, their_per_commitment_point, logger)
1253
1262
}
1254
1263
1264
+ pub ( crate ) fn update_funding_info ( & self , fund_outpoint : OutPoint , channel_value_satoshis : u64 ) -> Script {
1265
+ let mut inner = self . inner . lock ( ) . unwrap ( ) ;
1266
+ let script = inner. funding_info . 1 . clone ( ) ;
1267
+ if let Some ( original) = inner. original_funding_info . as_ref ( ) {
1268
+ if fund_outpoint == original. 0 {
1269
+ inner. original_funding_info = None ;
1270
+ }
1271
+ } else {
1272
+ inner. original_funding_info = Some ( ( inner. funding_info . 0 . clone ( ) , inner. funding_info . 1 . clone ( ) ) ) ;
1273
+ }
1274
+ inner. outputs_to_watch . insert ( fund_outpoint. txid , vec ! [ ( fund_outpoint. index as u32 , script. clone( ) ) ] ) ;
1275
+ inner. funding_info = ( fund_outpoint, script. clone ( ) ) ;
1276
+ inner. channel_value_satoshis = channel_value_satoshis;
1277
+ inner. onchain_tx_handler . signer . set_channel_value_satoshis ( channel_value_satoshis) ;
1278
+ script
1279
+ }
1280
+
1255
1281
#[ cfg( test) ]
1256
1282
fn provide_latest_holder_commitment_tx (
1257
1283
& self , holder_commitment_tx : HolderCommitmentTransaction ,
@@ -1308,6 +1334,11 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
1308
1334
self . inner . lock ( ) . unwrap ( ) . get_funding_txo ( ) . clone ( )
1309
1335
}
1310
1336
1337
+ ///
1338
+ pub fn get_original_funding_txo ( & self ) -> ( OutPoint , Script ) {
1339
+ self . inner . lock ( ) . unwrap ( ) . get_original_funding_txo ( ) . clone ( )
1340
+ }
1341
+
1311
1342
/// Gets a list of txids, with their output scripts (in the order they appear in the
1312
1343
/// transaction), which we must learn about spends of via block_connected().
1313
1344
pub fn get_outputs_to_watch ( & self ) -> Vec < ( Txid , Vec < ( u32 , Script ) > ) > {
@@ -1416,6 +1447,11 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
1416
1447
self . inner . lock ( ) . unwrap ( ) . get_latest_holder_commitment_txn ( logger)
1417
1448
}
1418
1449
1450
+ pub ( crate ) fn get_latest_holder_commitment_txn_internal < L : Deref > ( & self , logger : & L ) -> Vec < Transaction >
1451
+ where L :: Target : Logger {
1452
+ self . inner . lock ( ) . unwrap ( ) . get_latest_holder_commitment_txn_internal ( logger)
1453
+ }
1454
+
1419
1455
/// Unsafe test-only version of get_latest_holder_commitment_txn used by our test framework
1420
1456
/// to bypass HolderCommitmentTransaction state update lockdown after signature and generate
1421
1457
/// revoked commitment transaction.
@@ -2573,6 +2609,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2573
2609
& self . funding_info
2574
2610
}
2575
2611
2612
+ pub fn get_original_funding_txo ( & self ) -> & ( OutPoint , Script ) {
2613
+ & self . original_funding_info . as_ref ( ) . unwrap_or ( & self . funding_info )
2614
+ }
2615
+
2576
2616
pub fn get_outputs_to_watch ( & self ) -> & HashMap < Txid , Vec < ( u32 , Script ) > > {
2577
2617
// If we've detected a counterparty commitment tx on chain, we must include it in the set
2578
2618
// of outputs to watch for spends of, otherwise we're likely to lose user funds. Because
@@ -3018,8 +3058,12 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3018
3058
}
3019
3059
3020
3060
pub fn get_latest_holder_commitment_txn < L : Deref > ( & mut self , logger : & L ) -> Vec < Transaction > where L :: Target : Logger {
3021
- log_debug ! ( logger, "Getting signed latest holder commitment transaction!" ) ;
3022
3061
self . holder_tx_signed = true ;
3062
+ self . get_latest_holder_commitment_txn_internal ( logger)
3063
+ }
3064
+
3065
+ pub ( crate ) fn get_latest_holder_commitment_txn_internal < L : Deref > ( & mut self , logger : & L ) -> Vec < Transaction > where L :: Target : Logger {
3066
+ log_debug ! ( logger, "Getting signed latest holder commitment transaction!" ) ;
3023
3067
let commitment_tx = self . onchain_tx_handler . get_fully_signed_holder_tx ( & self . funding_redeemscript ) ;
3024
3068
let txid = commitment_tx. txid ( ) ;
3025
3069
let mut holder_transactions = vec ! [ commitment_tx] ;
@@ -3186,7 +3230,14 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3186
3230
// (except for HTLC transactions for channels with anchor outputs), which is an easy
3187
3231
// way to filter out any potential non-matching txn for lazy filters.
3188
3232
let prevout = & tx. input [ 0 ] . previous_output ;
3189
- if prevout. txid == self . funding_info . 0 . txid && prevout. vout == self . funding_info . 0 . index as u32 {
3233
+ let match_prevout = |outpoint : & OutPoint | {
3234
+ prevout. txid == outpoint. txid && prevout. vout == outpoint. index as u32
3235
+ } ;
3236
+ let is_split = tx. output . len ( ) == 2 && tx. output [ 0 ] . script_pubkey == tx. output [ 1 ] . script_pubkey ;
3237
+ let is_match = match_prevout ( & self . funding_info . 0 ) ||
3238
+ ( self . original_funding_info . is_some ( ) && match_prevout ( & self . original_funding_info . as_ref ( ) . unwrap ( ) . 0 ) && !is_split) ;
3239
+
3240
+ if is_match {
3190
3241
let mut balance_spendable_csv = None ;
3191
3242
log_info ! ( logger, "Channel {} closed by funding output spend in txid {}." ,
3192
3243
log_bytes!( self . funding_info. 0 . to_channel_id( ) ) , txid) ;
@@ -3945,6 +3996,16 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
3945
3996
index : Readable :: read ( reader) ?,
3946
3997
} ;
3947
3998
let funding_info = ( outpoint, Readable :: read ( reader) ?) ;
3999
+ let original_funding_info = match <u8 as Readable >:: read ( reader) ? {
4000
+ 0 => {
4001
+ let outpoint = Readable :: read ( reader) ?;
4002
+ let script = Readable :: read ( reader) ?;
4003
+ Some ( ( outpoint, script) )
4004
+ } ,
4005
+ 1 => { None } ,
4006
+ _ => return Err ( DecodeError :: InvalidValue ) ,
4007
+ } ;
4008
+
3948
4009
let current_counterparty_commitment_txid = Readable :: read ( reader) ?;
3949
4010
let prev_counterparty_commitment_txid = Readable :: read ( reader) ?;
3950
4011
@@ -4141,6 +4202,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
4141
4202
channel_keys_id,
4142
4203
holder_revocation_basepoint,
4143
4204
funding_info,
4205
+ original_funding_info,
4144
4206
current_counterparty_commitment_txid,
4145
4207
prev_counterparty_commitment_txid,
4146
4208
@@ -4399,7 +4461,8 @@ mod tests {
4399
4461
selected_contest_delay : 67 ,
4400
4462
} ) ,
4401
4463
funding_outpoint : Some ( funding_outpoint) ,
4402
- channel_type_features : ChannelTypeFeatures :: only_static_remote_key ( )
4464
+ channel_type_features : ChannelTypeFeatures :: only_static_remote_key ( ) ,
4465
+ original_funding_outpoint : None ,
4403
4466
} ;
4404
4467
// Prune with one old state and a holder commitment tx holding a few overlaps with the
4405
4468
// old state.
0 commit comments