From 91206defc16406134d6d9a50d6762e07387c37b5 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 14 Dec 2016 13:20:09 +0100 Subject: [PATCH] proper counting block fees and rewards --- verification/src/accept_block.rs | 37 ++++++++++++++------------------ verification/src/error.rs | 2 ++ 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/verification/src/accept_block.rs b/verification/src/accept_block.rs index 12c64bbb..87cd01c9 100644 --- a/verification/src/accept_block.rs +++ b/verification/src/accept_block.rs @@ -5,7 +5,7 @@ use work::block_reward_satoshi; use duplex_store::DuplexTransactionOutputProvider; use canon::CanonBlock; use constants::MAX_BLOCK_SIGOPS; -use error::Error; +use error::{Error, TransactionError}; /// Flexible verification of ordered block pub struct BlockAcceptor<'a> { @@ -115,11 +115,12 @@ impl<'a> BlockRule for BlockCoinbaseClaim<'a> { fn check(&self) -> Result<(), Error> { let store = DuplexTransactionOutputProvider::new(self.store, &*self.block); - let mut fee: u64 = 0; + let mut fees: u64 = 0; for tx in self.block.transactions.iter().skip(1) { + // (1) Total sum of all referenced outputs let mut incoming: u64 = 0; - for input in tx.inputs.iter() { + for input in tx.raw.inputs.iter() { let (sum, overflow) = incoming.overflowing_add( store.previous_transaction_output(&input.previous_output).map(|o| o.value).unwrap_or(0)); if overflow { @@ -128,31 +129,25 @@ impl<'a> BlockRule for BlockCoinbaseClaim<'a> { incoming = sum; } - let spends = tx.total_spends(); + // (2) Total sum of all outputs + let spends = tx.raw.total_spends(); - let (sum, overflow) = fee.overflowing_add(incoming); + // Difference between (1) and (2) + let (difference, overflow) = incoming.overflowing_sub(spends); if overflow { - return Err(Error:: + return Err(Error::Transaction(2, TransactionError::Overspend)) } + // Adding to total fees (with possible overflow) + let (sum, overflow) = fees.overflowing_add(difference); + if overflow { + return Err(Error::TransactionFeesOverflow) + } + + fees = sum; } - let available = self.block.transactions.iter() - .skip(1) - .flat_map(|tx| tx.raw.inputs.iter()) - .map(|input| store.previous_transaction_output(&input.previous_output).map(|o| o.value).unwrap_or(0)) - .sum::(); - - let spends = self.block.transactions.iter() - .skip(1) - .map(|tx| tx.raw.total_spends()) - .sum::(); - let claim = self.block.transactions[0].raw.total_spends(); - let (fees, overflow) = available.overflowing_sub(spends); - if overflow { - return Err(Error::TransactionFeesOverflow); - } let (reward, overflow) = fees.overflowing_add(block_reward_satoshi(self.height)); if overflow { diff --git a/verification/src/error.rs b/verification/src/error.rs index 72b2f8f0..50e7e7c5 100644 --- a/verification/src/error.rs +++ b/verification/src/error.rs @@ -40,6 +40,8 @@ pub enum Error { TransactionFeeAndRewardOverflow, /// Sum of the transaction fees in block exceeds u64::max TransactionFeesOverflow, + /// Sum of all referenced outputs in block transactions resulted in the overflow + ReferencedInputsSumOverflow } #[derive(Debug, PartialEq)]