@@ -256,30 +256,38 @@ pub(crate) struct HolderHTLCOutput {
256
256
amount_msat : u64 ,
257
257
/// Defaults to 0 for HTLC-Success transactions, which have no expiry
258
258
cltv_expiry : u32 ,
259
+ opt_anchors : Option < ( ) > ,
259
260
}
260
261
261
262
impl HolderHTLCOutput {
262
- pub ( crate ) fn build_offered ( amount_msat : u64 , cltv_expiry : u32 ) -> Self {
263
+ pub ( crate ) fn build_offered ( amount_msat : u64 , cltv_expiry : u32 , opt_anchors : bool ) -> Self {
263
264
HolderHTLCOutput {
264
265
preimage : None ,
265
266
amount_msat,
266
267
cltv_expiry,
268
+ opt_anchors : if opt_anchors { Some ( ( ) ) } else { None } ,
267
269
}
268
270
}
269
271
270
- pub ( crate ) fn build_accepted ( preimage : PaymentPreimage , amount_msat : u64 ) -> Self {
272
+ pub ( crate ) fn build_accepted ( preimage : PaymentPreimage , amount_msat : u64 , opt_anchors : bool ) -> Self {
271
273
HolderHTLCOutput {
272
274
preimage : Some ( preimage) ,
273
275
amount_msat,
274
276
cltv_expiry : 0 ,
277
+ opt_anchors : if opt_anchors { Some ( ( ) ) } else { None } ,
275
278
}
276
279
}
280
+
281
+ fn opt_anchors ( & self ) -> bool {
282
+ self . opt_anchors . is_some ( )
283
+ }
277
284
}
278
285
279
286
impl_writeable_tlv_based ! ( HolderHTLCOutput , {
280
287
( 0 , amount_msat, required) ,
281
288
( 2 , cltv_expiry, required) ,
282
- ( 4 , preimage, option)
289
+ ( 4 , preimage, option) ,
290
+ ( 6 , opt_anchors, ( default_value, None ) )
283
291
} ) ;
284
292
285
293
/// A struct to describe the channel output on the funding transaction.
@@ -334,10 +342,10 @@ impl PackageSolvingData {
334
342
PackageSolvingData :: RevokedHTLCOutput ( ref outp) => outp. amount ,
335
343
PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ref outp) => outp. htlc . amount_msat / 1000 ,
336
344
PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ref outp) => outp. htlc . amount_msat / 1000 ,
337
- // Note: Currently, amounts of holder outputs spending witnesses aren't used
338
- // as we can't malleate spending package to increase their feerate. This
339
- // should change with the remaining anchor output patchset.
340
- PackageSolvingData :: HolderHTLCOutput ( .. ) => unreachable ! ( ) ,
345
+ PackageSolvingData :: HolderHTLCOutput ( ref outp ) => {
346
+ debug_assert ! ( outp . opt_anchors ( ) ) ;
347
+ outp . amount_msat / 1000
348
+ } ,
341
349
PackageSolvingData :: HolderFundingOutput ( ref outp) => {
342
350
debug_assert ! ( outp. opt_anchors( ) ) ;
343
351
outp. funding_amount . unwrap ( )
@@ -346,18 +354,23 @@ impl PackageSolvingData {
346
354
amt
347
355
}
348
356
fn weight ( & self ) -> usize {
349
- let weight = match self {
350
- PackageSolvingData :: RevokedOutput ( ref outp) => { outp. weight as usize } ,
351
- PackageSolvingData :: RevokedHTLCOutput ( ref outp) => { outp. weight as usize } ,
352
- PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ref outp) => { weight_offered_htlc ( outp. opt_anchors ( ) ) as usize } ,
353
- PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ref outp) => { weight_received_htlc ( outp. opt_anchors ( ) ) as usize } ,
354
- // Note: Currently, weights of holder outputs spending witnesses aren't used
355
- // as we can't malleate spending package to increase their feerate. This
356
- // should change with the remaining anchor output patchset.
357
- PackageSolvingData :: HolderHTLCOutput ( ..) => { unreachable ! ( ) } ,
358
- PackageSolvingData :: HolderFundingOutput ( ..) => { unreachable ! ( ) } ,
359
- } ;
360
- weight
357
+ match self {
358
+ PackageSolvingData :: RevokedOutput ( ref outp) => outp. weight as usize ,
359
+ PackageSolvingData :: RevokedHTLCOutput ( ref outp) => outp. weight as usize ,
360
+ PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ref outp) => weight_offered_htlc ( outp. opt_anchors ( ) ) as usize ,
361
+ PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ref outp) => weight_received_htlc ( outp. opt_anchors ( ) ) as usize ,
362
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => {
363
+ debug_assert ! ( outp. opt_anchors( ) ) ;
364
+ if outp. preimage . is_none ( ) {
365
+ weight_offered_htlc ( true ) as usize
366
+ } else {
367
+ weight_received_htlc ( true ) as usize
368
+ }
369
+ } ,
370
+ // Since HolderFundingOutput maps to an untractable package that is already signed, its
371
+ // weight can be determined from the transaction itself.
372
+ PackageSolvingData :: HolderFundingOutput ( ..) => unreachable ! ( ) ,
373
+ }
361
374
}
362
375
fn is_compatible ( & self , input : & PackageSolvingData ) -> bool {
363
376
match self {
@@ -745,6 +758,7 @@ impl PackageTemplate {
745
758
pub ( crate ) fn requires_external_funding ( & self ) -> bool {
746
759
self . inputs . iter ( ) . find ( |input| match input. 1 {
747
760
PackageSolvingData :: HolderFundingOutput ( ref outp) => outp. opt_anchors ( ) ,
761
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => outp. opt_anchors ( ) ,
748
762
_ => false ,
749
763
} ) . is_some ( )
750
764
}
@@ -755,7 +769,11 @@ impl PackageTemplate {
755
769
PackageSolvingData :: RevokedHTLCOutput ( ..) => PackageMalleability :: Malleable ,
756
770
PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ..) => PackageMalleability :: Malleable ,
757
771
PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ..) => PackageMalleability :: Malleable ,
758
- PackageSolvingData :: HolderHTLCOutput ( ..) => PackageMalleability :: Untractable ,
772
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => if outp. opt_anchors ( ) {
773
+ PackageMalleability :: Malleable
774
+ } else {
775
+ PackageMalleability :: Untractable
776
+ } ,
759
777
PackageSolvingData :: HolderFundingOutput ( ..) => PackageMalleability :: Untractable ,
760
778
} ;
761
779
let mut inputs = Vec :: with_capacity ( 1 ) ;
@@ -804,7 +822,11 @@ impl Readable for PackageTemplate {
804
822
PackageSolvingData :: RevokedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , true ) } ,
805
823
PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , true ) } ,
806
824
PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , false ) } ,
807
- PackageSolvingData :: HolderHTLCOutput ( ..) => { ( PackageMalleability :: Untractable , false ) } ,
825
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => if outp. opt_anchors ( ) {
826
+ ( PackageMalleability :: Malleable , outp. preimage . is_some ( ) )
827
+ } else {
828
+ ( PackageMalleability :: Untractable , false )
829
+ } ,
808
830
PackageSolvingData :: HolderFundingOutput ( ..) => { ( PackageMalleability :: Untractable , false ) } ,
809
831
}
810
832
} else { return Err ( DecodeError :: InvalidValue ) ; } ;
@@ -964,7 +986,7 @@ mod tests {
964
986
( ) => {
965
987
{
966
988
let preimage = PaymentPreimage ( [ 2 ; 32 ] ) ;
967
- PackageSolvingData :: HolderHTLCOutput ( HolderHTLCOutput :: build_accepted( preimage, 0 ) )
989
+ PackageSolvingData :: HolderHTLCOutput ( HolderHTLCOutput :: build_accepted( preimage, 0 , false ) )
968
990
}
969
991
}
970
992
}
0 commit comments