@@ -462,7 +462,7 @@ impl TxOut {
462462
463463 /// Whether or not this output is a fee output
464464 pub fn is_fee ( & self ) -> bool {
465- self . script_pubkey . is_empty ( )
465+ self . script_pubkey . is_empty ( ) && self . value . is_explicit ( ) && self . asset . is_explicit ( )
466466 }
467467
468468 /// Extracts the minimum value from the rangeproof, if there is one, or returns 0.
@@ -612,6 +612,12 @@ impl Transaction {
612612 self . consensus_encode ( & mut enc) . unwrap ( ) ;
613613 bitcoin:: Wtxid :: from_engine ( enc)
614614 }
615+
616+ /// Get the total transaction fee.
617+ pub fn fee ( & self ) -> u64 {
618+ // All values should be explicit, so we don't have to assert that here.
619+ self . output . iter ( ) . filter ( |o| o. is_fee ( ) ) . filter_map ( |o| o. value . explicit ( ) ) . sum ( )
620+ }
615621}
616622
617623//TODO(stevenroose) remove this, it's incorrect
@@ -745,6 +751,7 @@ mod tests {
745751 assert_eq ! ( tx. output[ 1 ] . value, confidential:: Value :: Explicit ( 3300 ) ) ;
746752 assert_eq ! ( tx. output[ 0 ] . minimum_value( ) , 9999996700 ) ;
747753 assert_eq ! ( tx. output[ 1 ] . minimum_value( ) , 3300 ) ;
754+ assert_eq ! ( tx. fee( ) , 3300 ) ;
748755
749756 // CT transaction with explicit input (with script witness) and confidential outputs
750757 let tx: Transaction = hex_deserialize ! (
@@ -963,6 +970,8 @@ mod tests {
963970 assert_eq ! ( tx. output[ 1 ] . is_null_data( ) , false ) ;
964971 assert_eq ! ( tx. output[ 2 ] . is_null_data( ) , false ) ;
965972
973+ assert_eq ! ( tx. fee( ) , 36480 ) ;
974+
966975 // Coinbase tx
967976 let tx: Transaction = hex_deserialize ! (
968977 "0200000001010000000000000000000000000000000000000000000000000000\
@@ -997,6 +1006,7 @@ mod tests {
9971006 assert_eq ! ( tx. output[ 1 ] . is_pegout( ) , false ) ;
9981007 assert_eq ! ( tx. output[ 0 ] . pegout_data( ) , None ) ;
9991008 assert_eq ! ( tx. output[ 1 ] . pegout_data( ) , None ) ;
1009+ assert_eq ! ( tx. fee( ) , 0 ) ;
10001010 }
10011011
10021012 #[ test]
@@ -1120,6 +1130,7 @@ mod tests {
11201130 assert_eq ! ( tx. output[ 1 ] . is_pegout( ) , false ) ;
11211131 assert_eq ! ( tx. output[ 0 ] . pegout_data( ) , None ) ;
11221132 assert_eq ! ( tx. output[ 1 ] . pegout_data( ) , None ) ;
1133+ assert_eq ! ( tx. fee( ) , 6260 ) ;
11231134 }
11241135
11251136 #[ test]
@@ -1147,6 +1158,7 @@ mod tests {
11471158 assert_eq ! ( tx. output. len( ) , 1 ) ;
11481159 assert_eq ! ( tx. output[ 0 ] . is_null_data( ) , true ) ;
11491160 assert_eq ! ( tx. output[ 0 ] . is_pegout( ) , true ) ;
1161+ assert_eq ! ( tx. fee( ) , 0 ) ;
11501162 assert_eq ! (
11511163 tx. output[ 0 ] . pegout_data( ) ,
11521164 Some ( super :: PegoutData {
@@ -1498,6 +1510,7 @@ mod tests {
14981510 assert_eq ! ( tx. input. len( ) , 1 ) ;
14991511 assert_eq ! ( tx. output. len( ) , 3 ) ;
15001512 assert_eq ! ( tx. input[ 0 ] . has_issuance, true ) ;
1513+ assert_eq ! ( tx. fee( ) , 56400 ) ;
15011514 assert_eq ! (
15021515 tx. input[ 0 ] . asset_issuance,
15031516 AssetIssuance {
@@ -1620,6 +1633,7 @@ mod tests {
16201633
16211634 assert_eq ! ( tx. output[ 0 ] . asset, tx. output[ 1 ] . asset) ;
16221635 assert_eq ! ( tx. output[ 2 ] . asset, tx. output[ 1 ] . asset) ;
1636+ assert_eq ! ( tx. fee( ) , 1788 ) ;
16231637 }
16241638
16251639 #[ test]
@@ -1661,6 +1675,7 @@ mod tests {
16611675
16621676 assert_eq ! ( tx. output[ 0 ] . asset, tx. output[ 1 ] . asset) ;
16631677 assert_eq ! ( tx. output[ 2 ] . asset, tx. output[ 1 ] . asset) ;
1678+ assert_eq ! ( tx. fee( ) , 1788 ) ;
16641679 }
16651680
16661681 #[ test]
@@ -1701,6 +1716,7 @@ mod tests {
17011716
17021717 assert_eq ! ( tx. output[ 0 ] . asset, tx. output[ 1 ] . asset) ;
17031718 assert_eq ! ( tx. output[ 2 ] . asset, tx. output[ 1 ] . asset) ;
1719+ assert_eq ! ( tx. fee( ) , 1788 ) ;
17041720 }
17051721}
17061722
0 commit comments