@@ -1164,7 +1164,7 @@ mod test {
1164
1164
}
1165
1165
1166
1166
#[ test]
1167
- fn test_calculate_waste1 ( ) {
1167
+ fn test_calculate_waste_with_change ( ) {
1168
1168
let fee_rate = FeeRate :: from_sat_per_vb ( 11.0 ) ;
1169
1169
let long_term_fee_rate = FeeRate :: from_sat_per_vb ( 10.0 ) ;
1170
1170
let selected = generate_utxos_of_values ( vec ! [ 100_000_000 , 200_000_000 ] ) ;
@@ -1179,19 +1179,14 @@ mod test {
1179
1179
let size_of_change = 31 ;
1180
1180
let cost_of_change: u64 = ( size_of_change as f32 * fee_rate. as_sat_vb ( ) ) as u64 ;
1181
1181
1182
- let utxo_fee_diffs: Vec < u64 > = utxos
1183
- . into_iter ( )
1184
- . map ( |utxo| {
1185
- let fee_rate_diff = fee_rate - long_term_fee_rate;
1186
-
1187
- let fee =
1188
- fee_rate_diff. fee_wu ( TXIN_BASE_WEIGHT + utxo. weighted_utxo . satisfaction_weight ) ;
1182
+ let utxo_fee_diff: i64 = utxos. iter ( ) . fold ( 0 , |acc, utxo| {
1183
+ let fee_rate: i64 = utxo. fee as i64 ;
1184
+ let long_term_fee: i64 = long_term_fee_rate
1185
+ . fee_wu ( TXIN_BASE_WEIGHT + utxo. weighted_utxo . satisfaction_weight )
1186
+ as i64 ;
1189
1187
1190
- fee
1191
- } )
1192
- . collect ( ) ;
1193
-
1194
- let utxo_fee_diff: u64 = utxo_fee_diffs. iter ( ) . sum ( ) ;
1188
+ acc + fee_rate - long_term_fee
1189
+ } ) ;
1195
1190
1196
1191
// Waste with change is the change cost and difference between fee and long term fee
1197
1192
let waste = calculate_waste (
@@ -1202,16 +1197,16 @@ mod test {
1202
1197
long_term_fee_rate,
1203
1198
) ;
1204
1199
1205
- assert_eq ! ( waste. unwrap( ) , ( utxo_fee_diff + cost_of_change) as i64 ) ;
1200
+ assert_eq ! ( waste. unwrap( ) , ( utxo_fee_diff + cost_of_change as i64 ) ) ;
1206
1201
}
1207
1202
1208
1203
#[ test]
1209
- fn test_calculate_waste2 ( ) {
1204
+ fn test_calculate_waste_without_change ( ) {
1210
1205
let fee_rate = FeeRate :: from_sat_per_vb ( 11.0 ) ;
1211
1206
let long_term_fee_rate = FeeRate :: from_sat_per_vb ( 10.0 ) ;
1212
1207
let utxo_values = vec ! [ 100_000_000 , 200_000_000 ] ;
1213
1208
let selected = generate_utxos_of_values ( utxo_values. clone ( ) ) ;
1214
- let in_amt : u64 = utxo_values. iter ( ) . sum ( ) ;
1209
+ let available_value : u64 = utxo_values. iter ( ) . sum ( ) ;
1215
1210
let amount_needed = 200_000_000 ;
1216
1211
1217
1212
let utxos: Vec < OutputGroup > = selected
@@ -1220,33 +1215,107 @@ mod test {
1220
1215
. map ( |u| OutputGroup :: new ( u, fee_rate) )
1221
1216
. collect ( ) ;
1222
1217
1223
- let utxos_fee: u64 = utxos
1218
+ let utxos_fee: u64 = utxos. clone ( ) . iter ( ) . fold ( 0 , |acc, utxo| acc + utxo. fee ) ;
1219
+
1220
+ let utxo_fee_diff: i64 = utxos. iter ( ) . fold ( 0 , |acc, utxo| {
1221
+ let fee_rate: i64 = utxo. fee as i64 ;
1222
+ let long_term_fee: i64 = long_term_fee_rate
1223
+ . fee_wu ( TXIN_BASE_WEIGHT + utxo. weighted_utxo . satisfaction_weight )
1224
+ as i64 ;
1225
+
1226
+ acc + fee_rate - long_term_fee
1227
+ } ) ;
1228
+
1229
+ let excess = available_value - utxos_fee - amount_needed;
1230
+
1231
+ // Waste without change is the excess and difference between fee and long term fee
1232
+ let waste = calculate_waste ( selected, None , amount_needed, fee_rate, long_term_fee_rate) ;
1233
+
1234
+ assert_eq ! ( waste. unwrap( ) , ( utxo_fee_diff + excess as i64 ) ) ;
1235
+ }
1236
+
1237
+ #[ test]
1238
+ fn test_calculate_waste_with_change_not_set_to_none ( ) {
1239
+ let fee_rate = FeeRate :: from_sat_per_vb ( 11.0 ) ;
1240
+ let long_term_fee_rate = FeeRate :: from_sat_per_vb ( 10.0 ) ;
1241
+ let utxo_values = vec ! [ 100_000_000 , 200_000_000 ] ;
1242
+ let selected = generate_utxos_of_values ( utxo_values. clone ( ) ) ;
1243
+ let amount_needed = 200_000_000 ;
1244
+
1245
+ // Waste without change is the excess and difference between fee and long term fee
1246
+ let waste = calculate_waste (
1247
+ selected,
1248
+ Some ( 0 ) ,
1249
+ amount_needed,
1250
+ fee_rate,
1251
+ long_term_fee_rate,
1252
+ ) ;
1253
+
1254
+ match waste {
1255
+ Ok ( _) => assert ! ( false , "No change_cost means None, not Some(0)" ) ,
1256
+ Err ( e) => match e {
1257
+ Error :: Generic ( str) => {
1258
+ assert_eq ! ( str , "if there is not cost_of_change, set to None, not zero" )
1259
+ }
1260
+ _ => assert ! (
1261
+ false ,
1262
+ "No error thrown. Expected not zero cost_of_change not set to None error"
1263
+ ) ,
1264
+ } ,
1265
+ }
1266
+ }
1267
+
1268
+ #[ test]
1269
+ fn test_calculate_waste_with_negative_timing_cost ( ) {
1270
+ let fee_rate = FeeRate :: from_sat_per_vb ( 8.0 ) ;
1271
+ let long_term_fee_rate = FeeRate :: from_sat_per_vb ( 10.0 ) ;
1272
+ let utxo_values = vec ! [ 100_000_000 , 200_000_000 ] ;
1273
+ let selected = generate_utxos_of_values ( utxo_values. clone ( ) ) ;
1274
+ let available_value: u64 = utxo_values. iter ( ) . sum ( ) ;
1275
+ let amount_needed = 200_000_000 ;
1276
+
1277
+ let utxos: Vec < OutputGroup > = selected
1224
1278
. clone ( )
1225
1279
. into_iter ( )
1226
- . map ( |utxo| fee_rate. fee_wu ( TXIN_BASE_WEIGHT + utxo. weighted_utxo . satisfaction_weight ) )
1227
- . collect :: < Vec < u64 > > ( )
1228
- . iter ( )
1229
- . sum ( ) ;
1280
+ . map ( |u| OutputGroup :: new ( u, fee_rate) )
1281
+ . collect ( ) ;
1230
1282
1231
- let utxo_fee_diffs: Vec < u64 > = utxos
1232
- . into_iter ( )
1233
- . map ( |utxo| {
1234
- let fee_rate_diff = fee_rate - long_term_fee_rate;
1283
+ let utxos_fee: u64 = utxos. clone ( ) . iter ( ) . fold ( 0 , |acc, utxo| acc + utxo. fee ) ;
1235
1284
1236
- let fee =
1237
- fee_rate_diff. fee_wu ( TXIN_BASE_WEIGHT + utxo. weighted_utxo . satisfaction_weight ) ;
1285
+ let utxo_fee_diff: i64 = utxos. iter ( ) . fold ( 0 , |acc, utxo| {
1286
+ let fee_rate: i64 = utxo. fee as i64 ;
1287
+ let long_term_fee: i64 = long_term_fee_rate
1288
+ . fee_wu ( TXIN_BASE_WEIGHT + utxo. weighted_utxo . satisfaction_weight )
1289
+ as i64 ;
1238
1290
1239
- fee
1240
- } )
1241
- . collect ( ) ;
1291
+ acc + fee_rate - long_term_fee
1292
+ } ) ;
1293
+
1294
+ let excess = available_value - utxos_fee - amount_needed;
1295
+
1296
+ // Waste without change is the excess and difference between fee and long term fee
1297
+ let waste = calculate_waste ( selected, None , amount_needed, fee_rate, long_term_fee_rate) ;
1298
+
1299
+ assert_eq ! ( waste. unwrap( ) , ( utxo_fee_diff + excess as i64 ) ) ;
1300
+ }
1301
+
1302
+ #[ test]
1303
+ fn test_calculate_waste_with_no_timing_cost_and_no_creation_cost ( ) {
1304
+ let fee_rate = FeeRate :: from_sat_per_vb ( 10.0 ) ;
1305
+ let long_term_fee_rate = FeeRate :: from_sat_per_vb ( 10.0 ) ;
1306
+ let utxo_values = vec ! [ 200_000_000 ] ;
1307
+ let selected = generate_utxos_of_values ( utxo_values. clone ( ) ) ;
1242
1308
1243
- let utxo_fee_diff : u64 = utxo_fee_diffs . iter ( ) . sum ( ) ;
1309
+ let utxos_fee : u64 = fee_rate . fee_wu ( TXIN_BASE_WEIGHT + selected [ 0 ] . satisfaction_weight ) ;
1244
1310
1245
- let excess = in_amt - utxos_fee - amount_needed;
1311
+ // Build amount_needed to avoid any excess
1312
+ let amount_needed = utxo_values[ 0 ] - utxos_fee;
1246
1313
1247
1314
// Waste without change is the excess and difference between fee and long term fee
1248
- let waste = calculate_waste ( selected, None , 200_000_000 , fee_rate, long_term_fee_rate) ;
1315
+ let waste = calculate_waste ( selected, None , amount_needed , fee_rate, long_term_fee_rate) ;
1249
1316
1250
- assert_eq ! ( waste. unwrap( ) , ( utxo_fee_diff + excess) as i64 ) ;
1317
+ // There shouldn't be any waste if there is no
1318
+ // timing_cost nor creation_cost
1319
+ assert_eq ! ( waste. unwrap( ) , 0 ) ;
1251
1320
}
1252
1321
}
0 commit comments