@@ -484,7 +484,12 @@ where
484484
485485 tracing:: trace!( ?tx_id, "finished async checks" ) ;
486486
487- let ( miner_fee, sigops) = Self :: compute_fee_and_sigops ( tx. as_ref ( ) , & spent_utxos) ?;
487+ let miner_fee = if tx. is_coinbase ( ) {
488+ None
489+ } else {
490+ Some ( Self :: miner_fee ( tx. as_ref ( ) , & spent_utxos) ?)
491+ } ;
492+ let sigops = tx. sigops ( ) . map_err ( zebra_script:: Error :: from) ?;
488493
489494 Ok ( Response :: Block {
490495 tx_id,
@@ -577,6 +582,11 @@ where
577582 // the script interpreter.
578583 check:: mempool_standard_input_scripts ( tx. as_ref ( ) , & spent_outputs) ?;
579584
585+ // Apply ZIP-317 policy before expensive cryptographic verification.
586+ let miner_fee = Self :: miner_fee ( tx. as_ref ( ) , & spent_utxos) ?;
587+ let unpaid_actions = transaction:: zip317:: unpaid_actions ( & unmined_tx, miner_fee) ;
588+ transaction:: zip317:: mempool_checks ( unpaid_actions, miner_fee, unmined_tx. size ) ?;
589+
580590 let cached_ffi_transaction =
581591 Arc :: new ( CachedFfiTransaction :: new ( tx. clone ( ) , Arc :: new ( spent_outputs) , nu) . map_err ( |_| TransactionError :: UnsupportedByNetworkUpgrade ( tx. version ( ) , nu) ) ?) ;
582592
@@ -611,7 +621,7 @@ where
611621
612622 tracing:: trace!( ?tx_id, "finished async checks" ) ;
613623
614- let ( miner_fee , sigops) = Self :: compute_fee_and_sigops ( tx. as_ref ( ) , & spent_utxos ) ?;
624+ let sigops = tx. sigops ( ) . map_err ( zebra_script :: Error :: from ) ?;
615625
616626 // TODO: `spent_outputs` may not align with `tx.inputs()` when a transaction
617627 // spends both chain and mempool UTXOs (mempool outputs are appended last by
@@ -622,7 +632,7 @@ where
622632
623633 let transaction = VerifiedUnminedTx :: new (
624634 unmined_tx,
625- miner_fee. expect ( "fee should have been checked earlier" ) ,
635+ miner_fee,
626636 sigops,
627637 cached_ffi_transaction. p2sh_sigops ( ) ,
628638 spent_outputs. into ( ) ,
@@ -1478,32 +1488,17 @@ where
14781488 async_checks
14791489 }
14801490
1481- /// Computes the miner fee and transaction sigop count for `tx`.
1482- ///
1483- /// Returns `None` for coinbase transaction fees.
1484- fn compute_fee_and_sigops (
1491+ /// Calculate the miner fee from the transaction's value balance.
1492+ fn miner_fee (
14851493 tx : & Transaction ,
14861494 spent_utxos : & HashMap < transparent:: OutPoint , transparent:: Utxo > ,
1487- ) -> Result < ( Option < Amount < NonNegative > > , u32 ) , TransactionError > {
1488- // Get the `value_balance` to calculate the transaction fee.
1489- let value_balance = tx. value_balance ( spent_utxos) ;
1490-
1491- // Calculate the fee only for non-coinbase transactions.
1492- let mut miner_fee = None ;
1493- if !tx. is_coinbase ( ) {
1494- // TODO: deduplicate this code with remaining_transaction_value()?
1495- miner_fee = match value_balance {
1496- Ok ( vb) => match vb. remaining_transaction_value ( ) {
1497- Ok ( tx_rtv) => Some ( tx_rtv) ,
1498- Err ( _) => return Err ( TransactionError :: IncorrectFee ) ,
1499- } ,
1500- Err ( _) => return Err ( TransactionError :: IncorrectFee ) ,
1501- } ;
1495+ ) -> Result < Amount < NonNegative > , TransactionError > {
1496+ match tx. value_balance ( spent_utxos) {
1497+ Ok ( value_balance) => value_balance
1498+ . remaining_transaction_value ( )
1499+ . map_err ( |_| TransactionError :: IncorrectFee ) ,
1500+ Err ( _) => Err ( TransactionError :: IncorrectFee ) ,
15021501 }
1503-
1504- let sigops = tx. sigops ( ) . map_err ( zebra_script:: Error :: from) ?;
1505-
1506- Ok ( ( miner_fee, sigops) )
15071502 }
15081503}
15091504
0 commit comments