Sum transaction miner fees in the block verifier (#3093)
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
This commit is contained in:
parent
ec2c980bb1
commit
8e49663e31
|
@ -22,6 +22,7 @@ use tower::{Service, ServiceExt};
|
|||
use tracing::Instrument;
|
||||
|
||||
use zebra_chain::{
|
||||
amount::Amount,
|
||||
block::{self, Block},
|
||||
parameters::Network,
|
||||
transparent,
|
||||
|
@ -175,7 +176,7 @@ where
|
|||
// Since errors cause an early exit, try to do the
|
||||
// quick checks first.
|
||||
|
||||
// Field validity and structure checks
|
||||
// Quick field validity and structure checks
|
||||
let now = Utc::now();
|
||||
check::time_is_valid_at(&block.header, now, &height, &hash)
|
||||
.map_err(VerifyBlockError::Time)?;
|
||||
|
@ -184,13 +185,19 @@ where
|
|||
.transactions
|
||||
.get(0)
|
||||
.expect("must have coinbase transaction");
|
||||
// Check compatibility with ZIP-212 shielded Sapling and Orchard coinbase output decryption
|
||||
tx::check::coinbase_outputs_are_decryptable(coinbase_tx, network, height)?;
|
||||
check::subsidy_is_valid(&block, network)?;
|
||||
|
||||
// Validate `nExpiryHeight` consensus rules
|
||||
// TODO: check non-coinbase transaction expiry against the block height (#2387)
|
||||
// check the maximum expiry height for non-coinbase transactions (#2387)
|
||||
check::coinbase_expiry_height(&height, coinbase_tx, network)?;
|
||||
|
||||
// Now do the slower checks
|
||||
|
||||
// Check compatibility with ZIP-212 shielded Sapling and Orchard coinbase output decryption
|
||||
tx::check::coinbase_outputs_are_decryptable(coinbase_tx, network, height)?;
|
||||
|
||||
// Send transactions to the transaction verifier to be checked
|
||||
let mut async_checks = FuturesUnordered::new();
|
||||
|
||||
let known_utxos = Arc::new(transparent::new_ordered_outputs(
|
||||
|
@ -212,7 +219,11 @@ where
|
|||
}
|
||||
tracing::trace!(len = async_checks.len(), "built async tx checks");
|
||||
|
||||
// Get the transaction results back from the transaction verifier.
|
||||
|
||||
// Sum up some block totals from the transaction responses.
|
||||
let mut legacy_sigop_count = 0;
|
||||
let mut block_miner_fees = Ok(Amount::zero());
|
||||
|
||||
use futures::StreamExt;
|
||||
while let Some(result) = async_checks.next().await {
|
||||
|
@ -220,11 +231,26 @@ where
|
|||
let response = result
|
||||
.map_err(Into::into)
|
||||
.map_err(VerifyBlockError::Transaction)?;
|
||||
|
||||
assert!(
|
||||
matches!(response, tx::Response::Block { .. }),
|
||||
"unexpected response from transaction verifier: {:?}",
|
||||
response
|
||||
);
|
||||
|
||||
legacy_sigop_count += response
|
||||
.legacy_sigop_count()
|
||||
.expect("block transaction responses must have a legacy sigop count");
|
||||
|
||||
// Coinbase transactions consume the miner fee,
|
||||
// so they don't add any value to the block's total miner fee.
|
||||
if let Some(miner_fee) = response.miner_fee() {
|
||||
block_miner_fees += miner_fee;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the summed block totals
|
||||
|
||||
if legacy_sigop_count > MAX_BLOCK_SIGOPS {
|
||||
Err(BlockError::TooManyTransparentSignatureOperations {
|
||||
height,
|
||||
|
@ -233,10 +259,18 @@ where
|
|||
})?;
|
||||
}
|
||||
|
||||
// TODO: check miner subsidy and miner fees (#1162)
|
||||
let _block_miner_fees =
|
||||
block_miner_fees.map_err(|amount_error| BlockError::SummingMinerFees {
|
||||
height,
|
||||
hash,
|
||||
source: amount_error,
|
||||
})?;
|
||||
|
||||
// Finally, submit the block for contextual verification.
|
||||
let new_outputs = Arc::try_unwrap(known_utxos)
|
||||
.expect("all verification tasks using known_utxos are complete");
|
||||
|
||||
// Finally, submit the block for contextual verification.
|
||||
let prepared_block = zs::PreparedBlock {
|
||||
block,
|
||||
hash,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use thiserror::Error;
|
||||
|
||||
use zebra_chain::{block, orchard, sapling, sprout, transparent};
|
||||
use zebra_chain::{amount, block, orchard, sapling, sprout, transparent};
|
||||
|
||||
use crate::{block::MAX_BLOCK_SIGOPS, BoxError};
|
||||
|
||||
|
@ -229,4 +229,11 @@ pub enum BlockError {
|
|||
hash: zebra_chain::block::Hash,
|
||||
legacy_sigop_count: u64,
|
||||
},
|
||||
|
||||
#[error("summing miner fees for block {height:?} {hash:?} failed: {source:?}")]
|
||||
SummingMinerFees {
|
||||
height: zebra_chain::block::Height,
|
||||
hash: zebra_chain::block::Hash,
|
||||
source: amount::Error,
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue