@@ -930,6 +930,34 @@ impl Transaction {
930
930
( weight + 4 - 1 ) / 4
931
931
}
932
932
933
+ /// Get the "discount weight" of this transaction; this is the weight minus the output witnesses and minus the
934
+ /// differences between asset and nonce commitments from their explicit values.
935
+ pub fn discount_weight ( & self ) -> usize {
936
+ let mut weight = self . scaled_size ( 4 ) ;
937
+
938
+ for out in self . output . iter ( ) {
939
+ let rp_len = out. witness . rangeproof_len ( ) ;
940
+ let sp_len = out. witness . surjectionproof_len ( ) ;
941
+ let witness_weight = VarInt ( sp_len as u64 ) . size ( ) + sp_len + VarInt ( rp_len as u64 ) . size ( ) + rp_len;
942
+ weight -= witness_weight. saturating_sub ( 2 ) ; // explicit transactions have 1 byte for each empty proof
943
+ if out. value . is_confidential ( ) {
944
+ weight -= 33 - 9 ;
945
+ }
946
+ if out. nonce . is_confidential ( ) {
947
+ weight -= 33 - 1 ;
948
+ }
949
+ }
950
+
951
+ weight
952
+ }
953
+
954
+ /// Returns the "discount virtual size" (discountvsize) of this transaction.
955
+ ///
956
+ /// Will be `ceil(discount weight / 4.0)`.
957
+ pub fn discount_vsize ( & self ) -> usize {
958
+ ( self . discount_weight ( ) + 4 - 1 ) / 4
959
+ }
960
+
933
961
fn scaled_size ( & self , scale_factor : usize ) -> usize {
934
962
let witness_flag = self . has_witness ( ) ;
935
963
@@ -2399,4 +2427,88 @@ mod tests {
2399
2427
") ;
2400
2428
assert ! ( input. pegin_data( ) . is_none( ) ) ;
2401
2429
}
2430
+
2431
+ #[ test]
2432
+ fn discount_vsize ( ) {
2433
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/1in2out_pegin.hex" ) ) ;
2434
+ assert_eq ! ( tx. input. len( ) , 1 ) ;
2435
+ assert ! ( tx. input[ 0 ] . is_pegin( ) ) ;
2436
+ assert_eq ! ( tx. output. len( ) , 2 ) ;
2437
+ assert_eq ! ( tx. weight( ) , 2403 ) ;
2438
+ assert_eq ! ( tx. vsize( ) , 601 ) ;
2439
+ assert_eq ! ( tx. discount_weight( ) , 2403 ) ;
2440
+ assert_eq ! ( tx. discount_vsize( ) , 601 ) ;
2441
+
2442
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/1in2out_tx.hex" ) ) ;
2443
+ assert_eq ! ( tx. input. len( ) , 1 ) ;
2444
+ assert_eq ! ( tx. output. len( ) , 2 ) ;
2445
+ assert_eq ! ( tx. weight( ) , 5330 ) ;
2446
+ assert_eq ! ( tx. vsize( ) , 1333 ) ;
2447
+ assert_eq ! ( tx. discount_weight( ) , 1031 ) ;
2448
+ assert_eq ! ( tx. discount_vsize( ) , 258 ) ;
2449
+
2450
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/1in3out_tx.hex" ) ) ;
2451
+ assert_eq ! ( tx. input. len( ) , 1 ) ;
2452
+ assert_eq ! ( tx. output. len( ) , 3 ) ;
2453
+ assert_eq ! ( tx. weight( ) , 10107 ) ;
2454
+ assert_eq ! ( tx. vsize( ) , 2527 ) ;
2455
+ assert_eq ! ( tx. discount_weight( ) , 1509 ) ;
2456
+ assert_eq ! ( tx. discount_vsize( ) , 378 ) ;
2457
+
2458
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/2in3out_exp.hex" ) ) ;
2459
+ assert_eq ! ( tx. input. len( ) , 2 ) ;
2460
+ assert_eq ! ( tx. output. len( ) , 3 ) ;
2461
+ assert_eq ! ( tx. weight( ) , 1302 ) ;
2462
+ assert_eq ! ( tx. vsize( ) , 326 ) ;
2463
+ assert_eq ! ( tx. discount_weight( ) , 1302 ) ;
2464
+ assert_eq ! ( tx. discount_vsize( ) , 326 ) ;
2465
+
2466
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/2in3out_tx.hex" ) ) ;
2467
+ assert_eq ! ( tx. input. len( ) , 2 ) ;
2468
+ assert_eq ! ( tx. output. len( ) , 3 ) ;
2469
+ assert_eq ! ( tx. weight( ) , 10300 ) ;
2470
+ assert_eq ! ( tx. vsize( ) , 2575 ) ;
2471
+ assert_eq ! ( tx. discount_weight( ) , 1638 ) ;
2472
+ assert_eq ! ( tx. discount_vsize( ) , 410 ) ;
2473
+
2474
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/2in3out_tx2.hex" ) ) ;
2475
+ assert_eq ! ( tx. input. len( ) , 2 ) ;
2476
+ assert_eq ! ( tx. output. len( ) , 3 ) ;
2477
+ assert_eq ! ( tx. weight( ) , 10536 ) ;
2478
+ assert_eq ! ( tx. vsize( ) , 2634 ) ;
2479
+ assert_eq ! ( tx. discount_weight( ) , 1874 ) ;
2480
+ assert_eq ! ( tx. discount_vsize( ) , 469 ) ;
2481
+
2482
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/3in3out_tx.hex" ) ) ;
2483
+ assert_eq ! ( tx. input. len( ) , 3 ) ;
2484
+ assert_eq ! ( tx. output. len( ) , 3 ) ;
2485
+ assert_eq ! ( tx. weight( ) , 10922 ) ;
2486
+ assert_eq ! ( tx. vsize( ) , 2731 ) ;
2487
+ assert_eq ! ( tx. discount_weight( ) , 2196 ) ;
2488
+ assert_eq ! ( tx. discount_vsize( ) , 549 ) ;
2489
+
2490
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/4in3out_tx.hex" ) ) ;
2491
+ assert_eq ! ( tx. input. len( ) , 4 ) ;
2492
+ assert_eq ! ( tx. output. len( ) , 3 ) ;
2493
+ assert_eq ! ( tx. weight( ) , 11192 ) ;
2494
+ assert_eq ! ( tx. vsize( ) , 2798 ) ;
2495
+ assert_eq ! ( tx. discount_weight( ) , 2466 ) ;
2496
+ assert_eq ! ( tx. discount_vsize( ) , 617 ) ;
2497
+
2498
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/2in4out_tx.hex" ) ) ;
2499
+ assert_eq ! ( tx. input. len( ) , 2 ) ;
2500
+ assert_eq ! ( tx. output. len( ) , 4 ) ;
2501
+ assert_eq ! ( tx. weight( ) , 15261 ) ;
2502
+ assert_eq ! ( tx. vsize( ) , 3816 ) ;
2503
+ assert_eq ! ( tx. discount_weight( ) , 2268 ) ;
2504
+ assert_eq ! ( tx. discount_vsize( ) , 567 ) ;
2505
+
2506
+ let tx: Transaction = hex_deserialize ! ( include_str!( "../tests/data/2in5out_tx.hex" ) ) ;
2507
+ assert_eq ! ( tx. input. len( ) , 2 ) ;
2508
+ assert_eq ! ( tx. output. len( ) , 5 ) ;
2509
+ assert_eq ! ( tx. weight( ) , 20030 ) ;
2510
+ assert_eq ! ( tx. vsize( ) , 5008 ) ;
2511
+ assert_eq ! ( tx. discount_weight( ) , 2706 ) ;
2512
+ assert_eq ! ( tx. discount_vsize( ) , 677 ) ;
2513
+ }
2402
2514
}
0 commit comments