@@ -543,6 +543,7 @@ pub(crate) enum ChannelMonitorUpdateStep {
543543 feerate_per_kw : Option < u32 > ,
544544 to_broadcaster_value_sat : Option < u64 > ,
545545 to_countersignatory_value_sat : Option < u64 > ,
546+ tolocal_spk : ScriptBuf ,
546547 } ,
547548 PaymentPreimage {
548549 payment_preimage : PaymentPreimage ,
@@ -594,6 +595,7 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
594595 ( 4 , their_per_commitment_point, required) ,
595596 ( 5 , to_countersignatory_value_sat, option) ,
596597 ( 6 , htlc_outputs, required_vec) ,
598+ ( 8 , tolocal_spk, required) ,
597599 } ,
598600 ( 2 , PaymentPreimage ) => {
599601 ( 0 , payment_preimage, required) ,
@@ -893,6 +895,8 @@ pub(crate) struct ChannelMonitorImpl<Signer: ChannelSigner> {
893895 /// the payment hash from `HTLCOutputInCommitment` to claim even a revoked commitment
894896 /// transaction broadcast as we need to be able to construct the witness script in all cases.
895897 counterparty_claimable_outpoints : HashMap < Txid , Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > ,
898+ /// `to_local` outpoints
899+ tolocal_claimable_outpoints : HashMap < Txid , ScriptBuf > ,
896900 /// We cannot identify HTLC-Success or HTLC-Timeout transactions by themselves on the chain.
897901 /// Nor can we figure out their commitment numbers without the commitment transaction they are
898902 /// spending. Thus, in order to claim them via revocation key, we track all the counterparty
@@ -1133,6 +1137,11 @@ impl<Signer: ChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
11331137 htlc_source. as_ref ( ) . map ( |b| b. as_ref ( ) ) . write ( writer) ?;
11341138 }
11351139 }
1140+ writer. write_all ( & ( self . tolocal_claimable_outpoints . len ( ) as u64 ) . to_be_bytes ( ) ) ?;
1141+ for ( ref txid, ref spk) in self . tolocal_claimable_outpoints . iter ( ) {
1142+ writer. write_all ( & txid[ ..] ) ?;
1143+ spk. write ( writer) ?;
1144+ }
11361145
11371146 writer. write_all ( & ( self . counterparty_commitment_txn_on_chain . len ( ) as u64 ) . to_be_bytes ( ) ) ?;
11381147 for ( ref txid, commitment_number) in self . counterparty_commitment_txn_on_chain . iter ( ) {
@@ -1416,6 +1425,7 @@ impl<Signer: ChannelSigner> ChannelMonitor<Signer> {
14161425
14171426 commitment_secrets : CounterpartyCommitmentSecrets :: new ( ) ,
14181427 counterparty_claimable_outpoints : new_hash_map ( ) ,
1428+ tolocal_claimable_outpoints : new_hash_map ( ) ,
14191429 counterparty_commitment_txn_on_chain : new_hash_map ( ) ,
14201430 counterparty_hash_commitment_number : new_hash_map ( ) ,
14211431 counterparty_fulfilled_htlcs : new_hash_map ( ) ,
@@ -1466,15 +1476,15 @@ impl<Signer: ChannelSigner> ChannelMonitor<Signer> {
14661476 pub ( crate ) fn provide_initial_counterparty_commitment_tx < L : Deref > (
14671477 & self , txid : Txid , htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > ,
14681478 commitment_number : u64 , their_cur_per_commitment_point : PublicKey , feerate_per_kw : u32 ,
1469- to_broadcaster_value_sat : u64 , to_countersignatory_value_sat : u64 , logger : & L ,
1479+ to_broadcaster_value_sat : u64 , to_countersignatory_value_sat : u64 , logger : & L , tolocal_spk : ScriptBuf ,
14701480 )
14711481 where L :: Target : Logger
14721482 {
14731483 let mut inner = self . inner . lock ( ) . unwrap ( ) ;
14741484 let logger = WithChannelMonitor :: from_impl ( logger, & * inner, None ) ;
14751485 inner. provide_initial_counterparty_commitment_tx ( txid,
14761486 htlc_outputs, commitment_number, their_cur_per_commitment_point, feerate_per_kw,
1477- to_broadcaster_value_sat, to_countersignatory_value_sat, & logger) ;
1487+ to_broadcaster_value_sat, to_countersignatory_value_sat, & logger, tolocal_spk ) ;
14781488 }
14791489
14801490 /// Informs this monitor of the latest counterparty (ie non-broadcastable) commitment transaction.
@@ -1489,11 +1499,12 @@ impl<Signer: ChannelSigner> ChannelMonitor<Signer> {
14891499 commitment_number : u64 ,
14901500 their_per_commitment_point : PublicKey ,
14911501 logger : & L ,
1502+ tolocal_spk : ScriptBuf ,
14921503 ) where L :: Target : Logger {
14931504 let mut inner = self . inner . lock ( ) . unwrap ( ) ;
14941505 let logger = WithChannelMonitor :: from_impl ( logger, & * inner, None ) ;
14951506 inner. provide_latest_counterparty_commitment_tx (
1496- txid, htlc_outputs, commitment_number, their_per_commitment_point, & logger)
1507+ txid, htlc_outputs, commitment_number, their_per_commitment_point, & logger, tolocal_spk )
14971508 }
14981509
14991510 #[ cfg( test) ]
@@ -2835,6 +2846,7 @@ impl<Signer: ChannelSigner> ChannelMonitorImpl<Signer> {
28352846 & mut self , txid : Txid , htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > ,
28362847 commitment_number : u64 , their_per_commitment_point : PublicKey , feerate_per_kw : u32 ,
28372848 to_broadcaster_value : u64 , to_countersignatory_value : u64 , logger : & WithChannelMonitor < L > ,
2849+ tolocal_spk : ScriptBuf ,
28382850 ) where L :: Target : Logger {
28392851 self . initial_counterparty_commitment_info = Some ( ( their_per_commitment_point. clone ( ) ,
28402852 feerate_per_kw, to_broadcaster_value, to_countersignatory_value) ) ;
@@ -2845,13 +2857,14 @@ impl<Signer: ChannelSigner> ChannelMonitorImpl<Signer> {
28452857 }
28462858
28472859 self . provide_latest_counterparty_commitment_tx ( txid, htlc_outputs, commitment_number,
2848- their_per_commitment_point, logger) ;
2860+ their_per_commitment_point, logger, tolocal_spk ) ;
28492861 }
28502862
28512863 fn provide_latest_counterparty_commitment_tx < L : Deref > (
28522864 & mut self , txid : Txid ,
28532865 htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > ,
28542866 commitment_number : u64 , their_per_commitment_point : PublicKey , logger : & WithChannelMonitor < L > ,
2867+ tolocal_claimable_spk : ScriptBuf ,
28552868 ) where L :: Target : Logger {
28562869 // TODO: Encrypt the htlc_outputs data with the single-hash of the commitment transaction
28572870 // so that a remote monitor doesn't learn anything unless there is a malicious close.
@@ -2865,6 +2878,7 @@ impl<Signer: ChannelSigner> ChannelMonitorImpl<Signer> {
28652878 self . prev_counterparty_commitment_txid = self . current_counterparty_commitment_txid . take ( ) ;
28662879 self . current_counterparty_commitment_txid = Some ( txid) ;
28672880 self . counterparty_claimable_outpoints . insert ( txid, htlc_outputs. clone ( ) ) ;
2881+ self . tolocal_claimable_outpoints . insert ( txid, tolocal_claimable_spk) ;
28682882 self . current_counterparty_commitment_number = commitment_number;
28692883 //TODO: Merge this into the other per-counterparty-transaction output storage stuff
28702884 match self . their_cur_per_commitment_points {
@@ -3199,9 +3213,9 @@ impl<Signer: ChannelSigner> ChannelMonitorImpl<Signer> {
31993213 ret = Err ( ( ) ) ;
32003214 }
32013215 }
3202- ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => {
3216+ ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, tolocal_spk , .. } => {
32033217 log_trace ! ( logger, "Updating ChannelMonitor with latest counterparty commitment transaction info" ) ;
3204- self . provide_latest_counterparty_commitment_tx ( * commitment_txid, htlc_outputs. clone ( ) , * commitment_number, * their_per_commitment_point, logger)
3218+ self . provide_latest_counterparty_commitment_tx ( * commitment_txid, htlc_outputs. clone ( ) , * commitment_number, * their_per_commitment_point, logger, tolocal_spk . clone ( ) )
32053219 } ,
32063220 ChannelMonitorUpdateStep :: PaymentPreimage { payment_preimage, payment_info } => {
32073221 log_trace ! ( logger, "Updating ChannelMonitor with payment preimage" ) ;
@@ -3427,11 +3441,12 @@ impl<Signer: ChannelSigner> ChannelMonitorImpl<Signer> {
34273441 fn counterparty_commitment_txs_from_update ( & self , update : & ChannelMonitorUpdate ) -> Vec < CommitmentTransaction > {
34283442 update. updates . iter ( ) . filter_map ( |update| {
34293443 match update {
3444+ // TODO: must fix this ignore here - can you build the full commitment transaction back from just the update?
34303445 & ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { commitment_txid,
34313446 ref htlc_outputs, commitment_number, their_per_commitment_point,
34323447 feerate_per_kw : Some ( feerate_per_kw) ,
34333448 to_broadcaster_value_sat : Some ( to_broadcaster_value) ,
3434- to_countersignatory_value_sat : Some ( to_countersignatory_value) } => {
3449+ to_countersignatory_value_sat : Some ( to_countersignatory_value) , ref tolocal_spk } => {
34353450
34363451 let nondust_htlcs = htlc_outputs. iter ( ) . filter_map ( |( htlc, _) | {
34373452 htlc. transaction_output_index . map ( |_| ( htlc. clone ( ) , None ) )
@@ -3441,6 +3456,7 @@ impl<Signer: ChannelSigner> ChannelMonitorImpl<Signer> {
34413456 & their_per_commitment_point, to_broadcaster_value,
34423457 to_countersignatory_value, feerate_per_kw, nondust_htlcs) ;
34433458
3459+ debug_assert_eq ! ( & commitment_tx. trust( ) . revokeable_spk( ) , tolocal_spk) ;
34443460 debug_assert_eq ! ( commitment_tx. trust( ) . txid( ) , commitment_txid) ;
34453461
34463462 Some ( commitment_tx)
@@ -3510,21 +3526,22 @@ impl<Signer: ChannelSigner> ChannelMonitorImpl<Signer> {
35103526 let secret = self . get_secret ( commitment_number) . unwrap ( ) ;
35113527 let per_commitment_key = ignore_error ! ( SecretKey :: from_slice( & secret) ) ;
35123528 let per_commitment_point = PublicKey :: from_secret_key ( & self . onchain_tx_handler . secp_ctx , & per_commitment_key) ;
3513- let revokeable_spk = self . onchain_tx_handler . signer . get_revokeable_spk ( false , commitment_number, & per_commitment_point, & self . onchain_tx_handler . secp_ctx ) ;
35143529 let punishment_witness_weight = self . onchain_tx_handler . signer . get_punishment_witness_weight ( ) ;
35153530
35163531 // First, process non-htlc outputs (to_holder & to_counterparty)
3517- for ( idx, outp) in tx. output . iter ( ) . enumerate ( ) {
3518- if outp. script_pubkey == revokeable_spk {
3519- let revk_outp = RevokedOutput :: build ( per_commitment_point, per_commitment_key, outp. value , self . onchain_tx_handler . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) , punishment_witness_weight) ;
3520- let justice_package = PackageTemplate :: build_package (
3521- commitment_txid, idx as u32 ,
3522- PackageSolvingData :: RevokedOutput ( revk_outp) ,
3523- height + self . counterparty_commitment_params . on_counterparty_tx_csv as u32 ,
3524- ) ;
3525- claimable_outpoints. push ( justice_package) ;
3526- to_counterparty_output_info =
3527- Some ( ( idx. try_into ( ) . expect ( "Txn can't have more than 2^32 outputs" ) , outp. value ) ) ;
3532+ if let Some ( rev_spk) = self . tolocal_claimable_outpoints . get ( & commitment_txid) {
3533+ for ( idx, outp) in tx. output . iter ( ) . enumerate ( ) {
3534+ if & outp. script_pubkey == rev_spk {
3535+ let revk_outp = RevokedOutput :: build ( per_commitment_point, per_commitment_key, outp. value , self . onchain_tx_handler . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) , punishment_witness_weight) ;
3536+ let justice_package = PackageTemplate :: build_package (
3537+ commitment_txid, idx as u32 ,
3538+ PackageSolvingData :: RevokedOutput ( revk_outp) ,
3539+ height + self . counterparty_commitment_params . on_counterparty_tx_csv as u32 ,
3540+ ) ;
3541+ claimable_outpoints. push ( justice_package) ;
3542+ to_counterparty_output_info =
3543+ Some ( ( idx. try_into ( ) . expect ( "Txn can't have more than 2^32 outputs" ) , outp. value ) ) ;
3544+ }
35283545 }
35293546 }
35303547
@@ -3626,9 +3643,10 @@ impl<Signer: ChannelSigner> ChannelMonitorImpl<Signer> {
36263643 } else { return ( claimable_outpoints, to_counterparty_output_info) ; } ;
36273644
36283645 if let Some ( transaction) = tx {
3629- let revokeable_spk = self . onchain_tx_handler . signer . get_revokeable_spk ( false , commitment_number, & per_commitment_point, & self . onchain_tx_handler . secp_ctx ) ;
3646+ // unwrap because we are sure to be looking at a counterparty commitment transaction
3647+ let revokeable_spk = self . tolocal_claimable_outpoints . get ( & commitment_txid) . unwrap ( ) ;
36303648 for ( idx, outp) in transaction. output . iter ( ) . enumerate ( ) {
3631- if outp. script_pubkey == revokeable_spk {
3649+ if & outp. script_pubkey == revokeable_spk {
36323650 to_counterparty_output_info =
36333651 Some ( ( idx. try_into ( ) . expect ( "Can't have > 2^32 outputs" ) , outp. value ) ) ;
36343652 }
@@ -4815,6 +4833,15 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
48154833 return Err ( DecodeError :: InvalidValue ) ;
48164834 }
48174835 }
4836+ let tolocal_claimable_outpoints_len: u64 = Readable :: read ( reader) ?;
4837+ let mut tolocal_claimable_outpoints = hash_map_with_capacity ( cmp:: min ( tolocal_claimable_outpoints_len as usize , MAX_ALLOC_SIZE / 64 ) ) ;
4838+ for _ in 0 ..tolocal_claimable_outpoints_len {
4839+ let txid: Txid = Readable :: read ( reader) ?;
4840+ let spk: ScriptBuf = Readable :: read ( reader) ?;
4841+ if tolocal_claimable_outpoints. insert ( txid, spk) . is_some ( ) {
4842+ return Err ( DecodeError :: InvalidValue ) ;
4843+ }
4844+ }
48184845
48194846 let counterparty_commitment_txn_on_chain_len: u64 = Readable :: read ( reader) ?;
48204847 let mut counterparty_commitment_txn_on_chain = hash_map_with_capacity ( cmp:: min ( counterparty_commitment_txn_on_chain_len as usize , MAX_ALLOC_SIZE / 32 ) ) ;
@@ -5014,6 +5041,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50145041
50155042 commitment_secrets,
50165043 counterparty_claimable_outpoints,
5044+ tolocal_claimable_outpoints,
50175045 counterparty_commitment_txn_on_chain,
50185046 counterparty_hash_commitment_number,
50195047 counterparty_fulfilled_htlcs : counterparty_fulfilled_htlcs. unwrap ( ) ,
@@ -5289,9 +5317,9 @@ mod tests {
52895317 monitor. provide_latest_holder_commitment_tx ( dummy_commitment_tx. clone ( ) ,
52905318 htlcs. into_iter ( ) . map ( |( htlc, _) | ( htlc, Some ( dummy_sig) , None ) ) . collect ( ) ) . unwrap ( ) ;
52915319 monitor. provide_latest_counterparty_commitment_tx ( Txid :: from_byte_array ( Sha256 :: hash ( b"1" ) . to_byte_array ( ) ) ,
5292- preimages_slice_to_htlc_outputs ! ( preimages[ 5 ..15 ] ) , 281474976710655 , dummy_key, & logger) ;
5320+ preimages_slice_to_htlc_outputs ! ( preimages[ 5 ..15 ] ) , 281474976710655 , dummy_key, & logger, dummy_commitment_tx . trust ( ) . revokeable_spk ( ) ) ;
52935321 monitor. provide_latest_counterparty_commitment_tx ( Txid :: from_byte_array ( Sha256 :: hash ( b"2" ) . to_byte_array ( ) ) ,
5294- preimages_slice_to_htlc_outputs ! ( preimages[ 15 ..20 ] ) , 281474976710654 , dummy_key, & logger) ;
5322+ preimages_slice_to_htlc_outputs ! ( preimages[ 15 ..20 ] ) , 281474976710654 , dummy_key, & logger, dummy_commitment_tx . trust ( ) . revokeable_spk ( ) ) ;
52955323 for & ( ref preimage, ref hash) in preimages. iter ( ) {
52965324 let bounded_fee_estimator = LowerBoundedFeeEstimator :: new ( & fee_estimator) ;
52975325 monitor. provide_payment_preimage_unsafe_legacy (
@@ -5308,7 +5336,7 @@ mod tests {
53085336 test_preimages_exist ! ( & preimages[ 15 ..20 ] , monitor) ;
53095337
53105338 monitor. provide_latest_counterparty_commitment_tx ( Txid :: from_byte_array ( Sha256 :: hash ( b"3" ) . to_byte_array ( ) ) ,
5311- preimages_slice_to_htlc_outputs ! ( preimages[ 17 ..20 ] ) , 281474976710653 , dummy_key, & logger) ;
5339+ preimages_slice_to_htlc_outputs ! ( preimages[ 17 ..20 ] ) , 281474976710653 , dummy_key, & logger, dummy_commitment_tx . trust ( ) . revokeable_spk ( ) ) ;
53125340
53135341 // Now provide a further secret, pruning preimages 15-17
53145342 secret[ 0 ..32 ] . clone_from_slice ( & <Vec < u8 > >:: from_hex ( "c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964" ) . unwrap ( ) ) ;
@@ -5318,7 +5346,7 @@ mod tests {
53185346 test_preimages_exist ! ( & preimages[ 17 ..20 ] , monitor) ;
53195347
53205348 monitor. provide_latest_counterparty_commitment_tx ( Txid :: from_byte_array ( Sha256 :: hash ( b"4" ) . to_byte_array ( ) ) ,
5321- preimages_slice_to_htlc_outputs ! ( preimages[ 18 ..20 ] ) , 281474976710652 , dummy_key, & logger) ;
5349+ preimages_slice_to_htlc_outputs ! ( preimages[ 18 ..20 ] ) , 281474976710652 , dummy_key, & logger, dummy_commitment_tx . trust ( ) . revokeable_spk ( ) ) ;
53225350
53235351 // Now update holder commitment tx info, pruning only element 18 as we still care about the
53245352 // previous commitment tx's preimages too
0 commit comments