@@ -656,25 +656,26 @@ impl PackageSolvingData {
656656 _ => { panic ! ( "API Error!" ) ; }
657657 }
658658 }
659- fn absolute_tx_timelock ( & self , current_height : u32 ) -> u32 {
660- // We use `current_height` as our default locktime to discourage fee sniping and because
661- // transactions with it always propagate.
662- let absolute_timelock = match self {
663- PackageSolvingData :: RevokedOutput ( _) => current_height,
664- PackageSolvingData :: RevokedHTLCOutput ( _) => current_height,
665- PackageSolvingData :: CounterpartyOfferedHTLCOutput ( _) => current_height,
666- PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ref outp) => cmp:: max ( outp. htlc . cltv_expiry , current_height) ,
667- // HTLC timeout/success transactions rely on a fixed timelock due to the counterparty's
668- // signature.
659+ /// Some output types are locked with CHECKLOCKTIMEVERIFY and the spending transaction must
660+ /// have a minimum locktime, which is returned here.
661+ fn minimum_locktime ( & self ) -> Option < u32 > {
662+ match self {
663+ PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ref outp) => Some ( outp. htlc . cltv_expiry ) ,
664+ _ => None ,
665+ }
666+ }
667+ /// Some output types are pre-signed in such a way that the spending transaction must have an
668+ /// exact locktime. This returns that locktime for such outputs.
669+ fn signed_locktime ( & self ) -> Option < u32 > {
670+ match self {
669671 PackageSolvingData :: HolderHTLCOutput ( ref outp) => {
670672 if outp. preimage . is_some ( ) {
671673 debug_assert_eq ! ( outp. cltv_expiry, 0 ) ;
672674 }
673- outp. cltv_expiry
675+ Some ( outp. cltv_expiry )
674676 } ,
675- PackageSolvingData :: HolderFundingOutput ( _) => current_height,
676- } ;
677- absolute_timelock
677+ _ => None ,
678+ }
678679 }
679680
680681 fn map_output_type_flags ( & self ) -> ( PackageMalleability , bool ) {
@@ -863,36 +864,23 @@ impl PackageTemplate {
863864 }
864865 amounts
865866 }
866- pub ( crate ) fn package_locktime ( & self , current_height : u32 ) -> u32 {
867- let locktime = self . inputs . iter ( ) . map ( |( _, outp) | outp. absolute_tx_timelock ( current_height) )
868- . max ( ) . expect ( "There must always be at least one output to spend in a PackageTemplate" ) ;
869-
870- // If we ever try to aggregate a `HolderHTLCOutput`s with another output type, we'll likely
871- // end up with an incorrect transaction locktime since the counterparty has included it in
872- // its HTLC signature. This should never happen unless we decide to aggregate outputs across
873- // different channel commitments.
874- #[ cfg( debug_assertions) ] {
875- if self . inputs . iter ( ) . any ( |( _, outp) |
876- if let PackageSolvingData :: HolderHTLCOutput ( outp) = outp {
877- outp. preimage . is_some ( )
878- } else {
879- false
880- }
881- ) {
882- debug_assert_eq ! ( locktime, 0 ) ;
883- } ;
884- for timeout_htlc_expiry in self . inputs . iter ( ) . filter_map ( |( _, outp) |
885- if let PackageSolvingData :: HolderHTLCOutput ( outp) = outp {
886- if outp. preimage . is_none ( ) {
887- Some ( outp. cltv_expiry )
888- } else { None }
889- } else { None }
890- ) {
891- debug_assert_eq ! ( locktime, timeout_htlc_expiry) ;
892- }
867+ fn signed_locktime ( & self ) -> Option < u32 > {
868+ let signed_locktime = self . inputs . iter ( ) . find_map ( |( _, outp) | outp. signed_locktime ( ) ) ;
869+ #[ cfg( debug_assertions) ]
870+ for ( _, outp) in & self . inputs {
871+ debug_assert ! ( outp. signed_locktime( ) . is_none( ) || outp. signed_locktime( ) == signed_locktime) ;
893872 }
873+ signed_locktime
874+ }
875+ pub ( crate ) fn package_locktime ( & self , current_height : u32 ) -> u32 {
876+ let minimum_locktime = self . inputs . iter ( ) . filter_map ( |( _, outp) | outp. minimum_locktime ( ) ) . max ( ) ;
894877
895- locktime
878+ if let Some ( signed_locktime) = self . signed_locktime ( ) {
879+ debug_assert ! ( minimum_locktime. is_none( ) ) ;
880+ signed_locktime
881+ } else {
882+ core:: cmp:: max ( current_height, minimum_locktime. unwrap_or ( 0 ) )
883+ }
896884 }
897885 pub ( crate ) fn package_weight ( & self , destination_script : & Script ) -> u64 {
898886 let mut inputs_weight = 0 ;
@@ -1217,7 +1205,7 @@ where
12171205 F :: Target : FeeEstimator ,
12181206{
12191207 // If old feerate inferior to actual one given back by Fee Estimator, use it to compute new fee...
1220- let ( new_fee, new_feerate) = if let Some ( ( new_fee, new_feerate) ) =
1208+ let ( new_fee, new_feerate) = if let Some ( ( new_fee, new_feerate) ) =
12211209 compute_fee_from_spent_amounts ( input_amounts, predicted_weight, conf_target, fee_estimator, logger)
12221210 {
12231211 match feerate_strategy {
0 commit comments