@@ -485,6 +485,7 @@ pub fn execute_finalized_block(
485485 ProofHandling :: NoProofs ,
486486 ) ) ;
487487
488+ artifact_builder. with_available ( post_payment_balance_result. available_balance ( ) . copied ( ) ) ;
488489 let lane_id = transaction. transaction_lane ( ) ;
489490
490491 let allow_execution = {
@@ -494,21 +495,14 @@ pub fn execute_finalized_block(
494495 // amount in the happy path or the penalty amount in the sad path...in whichever case
495496 // the sad path is handled by is_penalty and the balance in the payment purse is
496497 // the penalty payment or the full amount but is 'sufficient' either way
497- let cost = artifact_builder. cost_to_use ( ) ;
498+ let actual_cost = artifact_builder. actual_cost ( ) ; // use actual cost here
498499 let is_sufficient_balance =
499- is_custom_payment || post_payment_balance_result. is_sufficient ( cost ) ;
500+ is_custom_payment || post_payment_balance_result. is_sufficient ( actual_cost ) ;
500501 let is_allowed_by_chainspec = chainspec. is_supported ( lane_id) ;
501502 let allow = is_not_penalized && is_sufficient_balance && is_allowed_by_chainspec;
502503 if !allow {
503504 let err_msg = {
504505 if !is_sufficient_balance {
505- if let Some ( available) = post_payment_balance_result. available_balance ( ) {
506- // they can't afford it so take available
507- let available = * available;
508- if available < cost {
509- artifact_builder. with_cost ( available) ;
510- }
511- }
512506 "Insufficient funds" . to_string ( )
513507 } else {
514508 format ! (
@@ -741,11 +735,13 @@ pub fn execute_finalized_block(
741735 let refund_amount = {
742736 let consumed =
743737 if balance_identifier. is_penalty ( ) || artifact_builder. error_message ( ) . is_some ( ) {
744- artifact_builder. limit ( ) // no refund for penalty
738+ artifact_builder. cost_to_use ( ) // no refund for penalty
745739 } else {
746740 artifact_builder. consumed ( )
747741 } ;
748742
743+ let available = artifact_builder. available ( ) . unwrap_or ( U512 :: zero ( ) ) ;
744+
749745 let refund_mode = match refund_handling {
750746 RefundHandling :: NoRefund => {
751747 if fee_handling. is_no_fee ( ) && is_custom_payment {
@@ -771,6 +767,7 @@ pub fn execute_finalized_block(
771767 consumed,
772768 source : Box :: new ( balance_identifier. clone ( ) ) ,
773769 ratio : refund_ratio,
770+ available,
774771 } ) ,
775772 RefundHandling :: Refund { refund_ratio } => {
776773 let source = Box :: new ( balance_identifier. clone ( ) ) ;
@@ -787,7 +784,6 @@ pub fn execute_finalized_block(
787784 // purposes of refund. instead, `BalanceIdentifier::Refund` is used by outer
788785 // logic, which is interpreted by inner logic to use the currently set
789786 // refund purse.
790- let target = Box :: new ( BalanceIdentifier :: Refund ) ;
791787 Some ( HandleRefundMode :: Refund {
792788 initiator_addr : Box :: new ( initiator_addr. clone ( ) ) ,
793789 limit : artifact_builder. limit ( ) ,
@@ -796,7 +792,8 @@ pub fn execute_finalized_block(
796792 cost : artifact_builder. cost_to_use ( ) ,
797793 ratio : refund_ratio,
798794 source,
799- target,
795+ target : Box :: new ( BalanceIdentifier :: Refund ) ,
796+ available,
800797 } )
801798 } else {
802799 // in normal payment handling we put a temporary processing hold
@@ -808,15 +805,14 @@ pub fn execute_finalized_block(
808805 // the churn of taking the token up front via transfer (which writes
809806 // multiple permanent records) and then transfer some of it back (which
810807 // writes more permanent records).
811- let calculated_refund_amount = HandleRefundMode :: CalculateAmount {
808+ Some ( HandleRefundMode :: CalculateAmount {
812809 limit : artifact_builder. limit ( ) ,
813810 gas_price : current_gas_price,
814811 consumed,
815812 cost : artifact_builder. cost_to_use ( ) ,
816813 ratio : refund_ratio,
817- source,
818- } ;
819- Some ( calculated_refund_amount)
814+ available,
815+ } )
820816 }
821817 }
822818 } ;
@@ -843,16 +839,22 @@ pub fn execute_finalized_block(
843839 }
844840 } ;
845841 artifact_builder. with_refund_amount ( refund_amount) ;
842+
843+ // take the lower of the difference between cost - refund OR available
844+ let fee_amount = artifact_builder
845+ . cost_to_use ( )
846+ . saturating_sub ( refund_amount)
847+ . min ( artifact_builder. available ( ) . unwrap_or ( U512 :: zero ( ) ) ) ;
848+
846849 // handle fees per the chainspec determined setting.
847850 let handle_fee_result = match fee_handling {
848851 FeeHandling :: NoFee => {
849852 // in this mode, a gas hold is placed on the payer's purse.
850- let amount = artifact_builder. cost_to_use ( ) . saturating_sub ( refund_amount) ;
851853 let hold_request = BalanceHoldRequest :: new_gas_hold (
852854 state_root_hash,
853855 protocol_version,
854856 balance_identifier,
855- amount ,
857+ fee_amount ,
856858 insufficient_balance_handling,
857859 ) ;
858860 let hold_result = scratch_state. balance_hold ( hold_request) ;
@@ -866,25 +868,23 @@ pub fn execute_finalized_block(
866868 state_root_hash,
867869 protocol_version,
868870 transaction_hash,
869- HandleFeeMode :: credit ( proposer. clone ( ) , amount , era_id) ,
871+ HandleFeeMode :: credit ( proposer. clone ( ) , fee_amount , era_id) ,
870872 ) ;
871873 scratch_state. handle_fee ( handle_fee_request)
872874 }
873875 FeeHandling :: Burn => {
874876 // in this mode, the fee portion is burned.
875- let amount = artifact_builder. cost_to_use ( ) . saturating_sub ( refund_amount) ;
876877 let handle_fee_request = HandleFeeRequest :: new (
877878 native_runtime_config. clone ( ) ,
878879 state_root_hash,
879880 protocol_version,
880881 transaction_hash,
881- HandleFeeMode :: burn ( balance_identifier, Some ( amount ) ) ,
882+ HandleFeeMode :: burn ( balance_identifier, Some ( fee_amount ) ) ,
882883 ) ;
883884 scratch_state. handle_fee ( handle_fee_request)
884885 }
885886 FeeHandling :: PayToProposer => {
886887 // in this mode, the consumed gas is paid as a fee to the block proposer
887- let amount = artifact_builder. cost_to_use ( ) . saturating_sub ( refund_amount) ;
888888 let handle_fee_request = HandleFeeRequest :: new (
889889 native_runtime_config. clone ( ) ,
890890 state_root_hash,
@@ -894,15 +894,14 @@ pub fn execute_finalized_block(
894894 Box :: new ( initiator_addr. clone ( ) ) ,
895895 balance_identifier,
896896 BalanceIdentifier :: Public ( * ( proposer. clone ( ) ) ) ,
897- amount ,
897+ fee_amount ,
898898 ) ,
899899 ) ;
900900 scratch_state. handle_fee ( handle_fee_request)
901901 }
902902 FeeHandling :: Accumulate => {
903903 // in this mode, consumed gas is accumulated into a single purse
904904 // for later distribution
905- let amount = artifact_builder. cost_to_use ( ) . saturating_sub ( refund_amount) ;
906905 let handle_fee_request = HandleFeeRequest :: new (
907906 native_runtime_config. clone ( ) ,
908907 state_root_hash,
@@ -912,7 +911,7 @@ pub fn execute_finalized_block(
912911 Box :: new ( initiator_addr. clone ( ) ) ,
913912 balance_identifier,
914913 BalanceIdentifier :: Accumulate ,
915- amount ,
914+ fee_amount ,
916915 ) ,
917916 ) ;
918917 scratch_state. handle_fee ( handle_fee_request)
0 commit comments