@@ -255,30 +255,38 @@ pub(crate) struct HolderHTLCOutput {
255
255
amount_msat : u64 ,
256
256
/// Defaults to 0 for HTLC-Success transactions, which have no expiry
257
257
cltv_expiry : u32 ,
258
+ opt_anchors : Option < ( ) > ,
258
259
}
259
260
260
261
impl HolderHTLCOutput {
261
- pub ( crate ) fn build_offered ( amount_msat : u64 , cltv_expiry : u32 ) -> Self {
262
+ pub ( crate ) fn build_offered ( amount_msat : u64 , cltv_expiry : u32 , opt_anchors : bool ) -> Self {
262
263
HolderHTLCOutput {
263
264
preimage : None ,
264
265
amount_msat,
265
266
cltv_expiry,
267
+ opt_anchors : if opt_anchors { Some ( ( ) ) } else { None } ,
266
268
}
267
269
}
268
270
269
- pub ( crate ) fn build_accepted ( preimage : PaymentPreimage , amount_msat : u64 ) -> Self {
271
+ pub ( crate ) fn build_accepted ( preimage : PaymentPreimage , amount_msat : u64 , opt_anchors : bool ) -> Self {
270
272
HolderHTLCOutput {
271
273
preimage : Some ( preimage) ,
272
274
amount_msat,
273
275
cltv_expiry : 0 ,
276
+ opt_anchors : if opt_anchors { Some ( ( ) ) } else { None } ,
274
277
}
275
278
}
279
+
280
+ fn opt_anchors ( & self ) -> bool {
281
+ self . opt_anchors . is_some ( )
282
+ }
276
283
}
277
284
278
285
impl_writeable_tlv_based ! ( HolderHTLCOutput , {
279
286
( 0 , amount_msat, required) ,
280
287
( 2 , cltv_expiry, required) ,
281
- ( 4 , preimage, option)
288
+ ( 4 , preimage, option) ,
289
+ ( 6 , opt_anchors, option)
282
290
} ) ;
283
291
284
292
/// A struct to describe the channel output on the funding transaction.
@@ -333,10 +341,10 @@ impl PackageSolvingData {
333
341
PackageSolvingData :: RevokedHTLCOutput ( ref outp) => outp. amount ,
334
342
PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ref outp) => outp. htlc . amount_msat / 1000 ,
335
343
PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ref outp) => outp. htlc . amount_msat / 1000 ,
336
- // Note: Currently, amounts of holder outputs spending witnesses aren't used
337
- // as we can't malleate spending package to increase their feerate. This
338
- // should change with the remaining anchor output patchset.
339
- PackageSolvingData :: HolderHTLCOutput ( .. ) => unreachable ! ( ) ,
344
+ PackageSolvingData :: HolderHTLCOutput ( ref outp ) => {
345
+ debug_assert ! ( outp . opt_anchors ( ) ) ;
346
+ outp . amount_msat / 1000
347
+ } ,
340
348
PackageSolvingData :: HolderFundingOutput ( ref outp) => {
341
349
debug_assert ! ( outp. opt_anchors( ) ) ;
342
350
outp. funding_amount . unwrap ( )
@@ -345,18 +353,23 @@ impl PackageSolvingData {
345
353
amt
346
354
}
347
355
fn weight ( & self ) -> usize {
348
- let weight = match self {
349
- PackageSolvingData :: RevokedOutput ( ref outp) => { outp. weight as usize } ,
350
- PackageSolvingData :: RevokedHTLCOutput ( ref outp) => { outp. weight as usize } ,
351
- PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ref outp) => { weight_offered_htlc ( outp. opt_anchors ( ) ) as usize } ,
352
- PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ref outp) => { weight_received_htlc ( outp. opt_anchors ( ) ) as usize } ,
353
- // Note: Currently, weights of holder outputs spending witnesses aren't used
354
- // as we can't malleate spending package to increase their feerate. This
355
- // should change with the remaining anchor output patchset.
356
- PackageSolvingData :: HolderHTLCOutput ( ..) => { unreachable ! ( ) } ,
357
- PackageSolvingData :: HolderFundingOutput ( ..) => { unreachable ! ( ) } ,
358
- } ;
359
- weight
356
+ match self {
357
+ PackageSolvingData :: RevokedOutput ( ref outp) => outp. weight as usize ,
358
+ PackageSolvingData :: RevokedHTLCOutput ( ref outp) => outp. weight as usize ,
359
+ PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ref outp) => weight_offered_htlc ( outp. opt_anchors ( ) ) as usize ,
360
+ PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ref outp) => weight_received_htlc ( outp. opt_anchors ( ) ) as usize ,
361
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => {
362
+ debug_assert ! ( outp. opt_anchors( ) ) ;
363
+ if outp. preimage . is_none ( ) {
364
+ weight_offered_htlc ( true ) as usize
365
+ } else {
366
+ weight_received_htlc ( true ) as usize
367
+ }
368
+ } ,
369
+ // Since HolderFundingOutput maps to an untractable package that is already signed, its
370
+ // weight can be determined from the transaction itself.
371
+ PackageSolvingData :: HolderFundingOutput ( ..) => unreachable ! ( ) ,
372
+ }
360
373
}
361
374
fn is_compatible ( & self , input : & PackageSolvingData ) -> bool {
362
375
match self {
@@ -740,6 +753,7 @@ impl PackageTemplate {
740
753
pub ( crate ) fn requires_external_funding ( & self ) -> bool {
741
754
self . inputs . iter ( ) . find ( |input| match input. 1 {
742
755
PackageSolvingData :: HolderFundingOutput ( ref outp) => outp. opt_anchors ( ) ,
756
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => outp. opt_anchors ( ) ,
743
757
_ => false ,
744
758
} ) . is_some ( )
745
759
}
@@ -750,7 +764,11 @@ impl PackageTemplate {
750
764
PackageSolvingData :: RevokedHTLCOutput ( ..) => PackageMalleability :: Malleable ,
751
765
PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ..) => PackageMalleability :: Malleable ,
752
766
PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ..) => PackageMalleability :: Malleable ,
753
- PackageSolvingData :: HolderHTLCOutput ( ..) => PackageMalleability :: Untractable ,
767
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => if outp. opt_anchors ( ) {
768
+ PackageMalleability :: Malleable
769
+ } else {
770
+ PackageMalleability :: Untractable
771
+ } ,
754
772
PackageSolvingData :: HolderFundingOutput ( ..) => PackageMalleability :: Untractable ,
755
773
} ;
756
774
let mut inputs = Vec :: with_capacity ( 1 ) ;
@@ -799,7 +817,11 @@ impl Readable for PackageTemplate {
799
817
PackageSolvingData :: RevokedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , true ) } ,
800
818
PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , true ) } ,
801
819
PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , false ) } ,
802
- PackageSolvingData :: HolderHTLCOutput ( ..) => { ( PackageMalleability :: Untractable , false ) } ,
820
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => if outp. opt_anchors ( ) {
821
+ ( PackageMalleability :: Malleable , outp. preimage . is_some ( ) )
822
+ } else {
823
+ ( PackageMalleability :: Untractable , false )
824
+ } ,
803
825
PackageSolvingData :: HolderFundingOutput ( ..) => { ( PackageMalleability :: Untractable , false ) } ,
804
826
}
805
827
} else { return Err ( DecodeError :: InvalidValue ) ; } ;
@@ -959,7 +981,7 @@ mod tests {
959
981
( ) => {
960
982
{
961
983
let preimage = PaymentPreimage ( [ 2 ; 32 ] ) ;
962
- PackageSolvingData :: HolderHTLCOutput ( HolderHTLCOutput :: build_accepted( preimage, 0 ) )
984
+ PackageSolvingData :: HolderHTLCOutput ( HolderHTLCOutput :: build_accepted( preimage, 0 , false ) )
963
985
}
964
986
}
965
987
}
0 commit comments