@@ -482,6 +482,24 @@ impl PackageSolvingData {
482
482
} ;
483
483
absolute_timelock
484
484
}
485
+
486
+ fn map_output_type_flags ( & self ) -> ( PackageMalleability , bool ) {
487
+ // Post-anchor, aggregation of outputs of different types is unsafe. See https://github.com/lightning/bolts/pull/803.
488
+ let ( malleability, aggregable) = match self {
489
+ PackageSolvingData :: RevokedOutput ( RevokedOutput { is_counterparty_balance_on_anchors : true , .. } ) => { ( PackageMalleability :: Malleable , false ) } ,
490
+ PackageSolvingData :: RevokedOutput ( RevokedOutput { is_counterparty_balance_on_anchors : false , .. } ) => { ( PackageMalleability :: Malleable , true ) } ,
491
+ PackageSolvingData :: RevokedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , true ) } ,
492
+ PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , true ) } ,
493
+ PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , false ) } ,
494
+ PackageSolvingData :: HolderHTLCOutput ( ref outp) => if outp. opt_anchors ( ) {
495
+ ( PackageMalleability :: Malleable , outp. preimage . is_some ( ) )
496
+ } else {
497
+ ( PackageMalleability :: Untractable , false )
498
+ } ,
499
+ PackageSolvingData :: HolderFundingOutput ( ..) => { ( PackageMalleability :: Untractable , false ) } ,
500
+ } ;
501
+ ( malleability, aggregable)
502
+ }
485
503
}
486
504
487
505
impl_writeable_tlv_based_enum ! ( PackageSolvingData , ;
@@ -494,8 +512,7 @@ impl_writeable_tlv_based_enum!(PackageSolvingData, ;
494
512
) ;
495
513
496
514
/// A malleable package might be aggregated with other packages to save on fees.
497
- /// A untractable package has been counter-signed and aggregable will break cached counterparty
498
- /// signatures.
515
+ /// A untractable package has been counter-signed and aggregable will break cached counterparty signatures.
499
516
#[ derive( Clone , PartialEq , Eq ) ]
500
517
pub ( crate ) enum PackageMalleability {
501
518
Malleable ,
@@ -829,8 +846,8 @@ impl PackageTemplate {
829
846
} ) . is_some ( )
830
847
}
831
848
832
- pub ( crate ) fn build_package ( txid : Txid , vout : u32 , input_solving_data : PackageSolvingData , soonest_conf_deadline : u32 , aggregable : bool , height_original : u32 ) -> Self {
833
- let ( malleability, aggregable) = Self :: map_output_type_flags ( & input_solving_data) ;
849
+ pub ( crate ) fn build_package ( txid : Txid , vout : u32 , input_solving_data : PackageSolvingData , soonest_conf_deadline : u32 , height_original : u32 ) -> Self {
850
+ let ( malleability, aggregable) = PackageSolvingData :: map_output_type_flags ( & input_solving_data) ;
834
851
let mut inputs = Vec :: with_capacity ( 1 ) ;
835
852
inputs. push ( ( BitcoinOutPoint { txid, vout } , input_solving_data) ) ;
836
853
PackageTemplate {
@@ -843,19 +860,6 @@ impl PackageTemplate {
843
860
height_original,
844
861
}
845
862
}
846
-
847
- fn map_output_type_flags ( input_solving_data : & PackageSolvingData ) -> ( PackageMalleability , bool ) {
848
- let ( malleability, aggregable) = match input_solving_data {
849
- PackageSolvingData :: RevokedOutput ( RevokedOutput { is_counterparty_balance_on_anchors : true , .. } ) => { ( PackageMalleability :: Malleable , false ) } ,
850
- PackageSolvingData :: RevokedOutput ( RevokedOutput { is_counterparty_balance_on_anchors : false , .. } ) => { ( PackageMalleability :: Malleable , true ) } ,
851
- PackageSolvingData :: RevokedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , true ) } ,
852
- PackageSolvingData :: CounterpartyOfferedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , true ) } ,
853
- PackageSolvingData :: CounterpartyReceivedHTLCOutput ( ..) => { ( PackageMalleability :: Malleable , false ) } ,
854
- PackageSolvingData :: HolderHTLCOutput ( ..) => { ( PackageMalleability :: Untractable , false ) } ,
855
- PackageSolvingData :: HolderFundingOutput ( ..) => { ( PackageMalleability :: Untractable , false ) } ,
856
- } ;
857
- ( malleability, aggregable)
858
- }
859
863
}
860
864
861
865
impl Writeable for PackageTemplate {
@@ -885,7 +889,7 @@ impl Readable for PackageTemplate {
885
889
inputs. push ( ( outpoint, rev_outp) ) ;
886
890
}
887
891
let ( malleability, aggregable) = if let Some ( ( _, lead_input) ) = inputs. first ( ) {
888
- Self :: map_output_type_flags ( & lead_input)
892
+ PackageSolvingData :: map_output_type_flags ( & lead_input)
889
893
} else { return Err ( DecodeError :: InvalidValue ) ; } ;
890
894
let mut soonest_conf_deadline = 0 ;
891
895
let mut feerate_previous = 0 ;
@@ -1073,8 +1077,8 @@ mod tests {
1073
1077
let secp_ctx = Secp256k1 :: new ( ) ;
1074
1078
let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1075
1079
1076
- let mut package_one_hundred = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
1077
- let package_two_hundred = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , true , 200 ) ;
1080
+ let mut package_one_hundred = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , 100 ) ;
1081
+ let package_two_hundred = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , 200 ) ;
1078
1082
package_one_hundred. merge_package ( package_two_hundred) ;
1079
1083
}
1080
1084
@@ -1086,8 +1090,8 @@ mod tests {
1086
1090
let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1087
1091
let htlc_outp = dumb_htlc_output ! ( ) ;
1088
1092
1089
- let mut untractable_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
1090
- let malleable_package = PackageTemplate :: build_package ( txid, 1 , htlc_outp. clone ( ) , 1000 , true , 100 ) ;
1093
+ let mut untractable_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , 100 ) ;
1094
+ let malleable_package = PackageTemplate :: build_package ( txid, 1 , htlc_outp. clone ( ) , 1000 , 100 ) ;
1091
1095
untractable_package. merge_package ( malleable_package) ;
1092
1096
}
1093
1097
@@ -1099,8 +1103,8 @@ mod tests {
1099
1103
let htlc_outp = dumb_htlc_output ! ( ) ;
1100
1104
let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1101
1105
1102
- let mut malleable_package = PackageTemplate :: build_package ( txid, 0 , htlc_outp. clone ( ) , 1000 , true , 100 ) ;
1103
- let untractable_package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
1106
+ let mut malleable_package = PackageTemplate :: build_package ( txid, 0 , htlc_outp. clone ( ) , 1000 , 100 ) ;
1107
+ let untractable_package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , 100 ) ;
1104
1108
malleable_package. merge_package ( untractable_package) ;
1105
1109
}
1106
1110
@@ -1109,10 +1113,11 @@ mod tests {
1109
1113
fn test_package_noaggregation_to ( ) {
1110
1114
let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
1111
1115
let secp_ctx = Secp256k1 :: new ( ) ;
1112
- let revk_outp = dumb_revk_output ! ( secp_ctx, true ) ;
1116
+ let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1117
+ let revk_outp_counterparty_balance = dumb_revk_output ! ( secp_ctx, true ) ;
1113
1118
1114
- let mut noaggregation_package = PackageTemplate :: build_package ( txid, 0 , revk_outp . clone ( ) , 1000 , false , 100 ) ;
1115
- let aggregation_package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
1119
+ let mut noaggregation_package = PackageTemplate :: build_package ( txid, 0 , revk_outp_counterparty_balance . clone ( ) , 1000 , 100 ) ;
1120
+ let aggregation_package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , 100 ) ;
1116
1121
noaggregation_package. merge_package ( aggregation_package) ;
1117
1122
}
1118
1123
@@ -1121,10 +1126,11 @@ mod tests {
1121
1126
fn test_package_noaggregation_from ( ) {
1122
1127
let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
1123
1128
let secp_ctx = Secp256k1 :: new ( ) ;
1124
- let revk_outp = dumb_revk_output ! ( secp_ctx, true ) ;
1129
+ let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1130
+ let revk_outp_counterparty_balance = dumb_revk_output ! ( secp_ctx, true ) ;
1125
1131
1126
- let mut aggregation_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
1127
- let noaggregation_package = PackageTemplate :: build_package ( txid, 1 , revk_outp . clone ( ) , 1000 , false , 100 ) ;
1132
+ let mut aggregation_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , 100 ) ;
1133
+ let noaggregation_package = PackageTemplate :: build_package ( txid, 1 , revk_outp_counterparty_balance . clone ( ) , 1000 , 100 ) ;
1128
1134
aggregation_package. merge_package ( noaggregation_package) ;
1129
1135
}
1130
1136
@@ -1135,9 +1141,9 @@ mod tests {
1135
1141
let secp_ctx = Secp256k1 :: new ( ) ;
1136
1142
let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1137
1143
1138
- let mut empty_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
1144
+ let mut empty_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , 100 ) ;
1139
1145
empty_package. inputs = vec ! [ ] ;
1140
- let package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
1146
+ let package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , 100 ) ;
1141
1147
empty_package. merge_package ( package) ;
1142
1148
}
1143
1149
@@ -1149,8 +1155,8 @@ mod tests {
1149
1155
let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1150
1156
let counterparty_outp = dumb_counterparty_output ! ( secp_ctx, 0 , false ) ;
1151
1157
1152
- let mut revoked_package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 1000 , true , 100 ) ;
1153
- let counterparty_package = PackageTemplate :: build_package ( txid, 1 , counterparty_outp, 1000 , true , 100 ) ;
1158
+ let mut revoked_package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 1000 , 100 ) ;
1159
+ let counterparty_package = PackageTemplate :: build_package ( txid, 1 , counterparty_outp, 1000 , 100 ) ;
1154
1160
revoked_package. merge_package ( counterparty_package) ;
1155
1161
}
1156
1162
@@ -1162,9 +1168,9 @@ mod tests {
1162
1168
let revk_outp_two = dumb_revk_output ! ( secp_ctx, false ) ;
1163
1169
let revk_outp_three = dumb_revk_output ! ( secp_ctx, false ) ;
1164
1170
1165
- let mut package_one = PackageTemplate :: build_package ( txid, 0 , revk_outp_one, 1000 , true , 100 ) ;
1166
- let package_two = PackageTemplate :: build_package ( txid, 1 , revk_outp_two, 1000 , true , 100 ) ;
1167
- let package_three = PackageTemplate :: build_package ( txid, 2 , revk_outp_three, 1000 , true , 100 ) ;
1171
+ let mut package_one = PackageTemplate :: build_package ( txid, 0 , revk_outp_one, 1000 , 100 ) ;
1172
+ let package_two = PackageTemplate :: build_package ( txid, 1 , revk_outp_two, 1000 , 100 ) ;
1173
+ let package_three = PackageTemplate :: build_package ( txid, 2 , revk_outp_three, 1000 , 100 ) ;
1168
1174
1169
1175
package_one. merge_package ( package_two) ;
1170
1176
package_one. merge_package ( package_three) ;
@@ -1187,7 +1193,7 @@ mod tests {
1187
1193
let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
1188
1194
let htlc_outp_one = dumb_htlc_output ! ( ) ;
1189
1195
1190
- let mut package_one = PackageTemplate :: build_package ( txid, 0 , htlc_outp_one, 1000 , true , 100 ) ;
1196
+ let mut package_one = PackageTemplate :: build_package ( txid, 0 , htlc_outp_one, 1000 , 100 ) ;
1191
1197
let ret_split = package_one. split_package ( & BitcoinOutPoint { txid, vout : 0 } ) ;
1192
1198
assert ! ( ret_split. is_none( ) ) ;
1193
1199
}
@@ -1198,7 +1204,7 @@ mod tests {
1198
1204
let secp_ctx = Secp256k1 :: new ( ) ;
1199
1205
let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1200
1206
1201
- let mut package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 1000 , true , 100 ) ;
1207
+ let mut package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 1000 , 100 ) ;
1202
1208
assert_eq ! ( package. timer( ) , 100 ) ;
1203
1209
package. set_timer ( 101 ) ;
1204
1210
assert_eq ! ( package. timer( ) , 101 ) ;
@@ -1210,7 +1216,7 @@ mod tests {
1210
1216
let secp_ctx = Secp256k1 :: new ( ) ;
1211
1217
let counterparty_outp = dumb_counterparty_output ! ( secp_ctx, 1_000_000 , false ) ;
1212
1218
1213
- let package = PackageTemplate :: build_package ( txid, 0 , counterparty_outp, 1000 , true , 100 ) ;
1219
+ let package = PackageTemplate :: build_package ( txid, 0 , counterparty_outp, 1000 , 100 ) ;
1214
1220
assert_eq ! ( package. package_amount( ) , 1000 ) ;
1215
1221
}
1216
1222
@@ -1224,22 +1230,22 @@ mod tests {
1224
1230
1225
1231
{
1226
1232
let revk_outp = dumb_revk_output ! ( secp_ctx, false ) ;
1227
- let package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 0 , true , 100 ) ;
1233
+ let package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 0 , 100 ) ;
1228
1234
assert_eq ! ( package. package_weight( & Script :: new( ) ) , weight_sans_output + WEIGHT_REVOKED_OUTPUT as usize ) ;
1229
1235
}
1230
1236
1231
1237
{
1232
1238
for & opt_anchors in [ false , true ] . iter ( ) {
1233
1239
let counterparty_outp = dumb_counterparty_output ! ( secp_ctx, 1_000_000 , opt_anchors) ;
1234
- let package = PackageTemplate :: build_package ( txid, 0 , counterparty_outp, 1000 , true , 100 ) ;
1240
+ let package = PackageTemplate :: build_package ( txid, 0 , counterparty_outp, 1000 , 100 ) ;
1235
1241
assert_eq ! ( package. package_weight( & Script :: new( ) ) , weight_sans_output + weight_received_htlc( opt_anchors) as usize ) ;
1236
1242
}
1237
1243
}
1238
1244
1239
1245
{
1240
1246
for & opt_anchors in [ false , true ] . iter ( ) {
1241
1247
let counterparty_outp = dumb_counterparty_offered_output ! ( secp_ctx, 1_000_000 , opt_anchors) ;
1242
- let package = PackageTemplate :: build_package ( txid, 0 , counterparty_outp, 1000 , true , 100 ) ;
1248
+ let package = PackageTemplate :: build_package ( txid, 0 , counterparty_outp, 1000 , 100 ) ;
1243
1249
assert_eq ! ( package. package_weight( & Script :: new( ) ) , weight_sans_output + weight_offered_htlc( opt_anchors) as usize ) ;
1244
1250
}
1245
1251
}
0 commit comments