proper counting block fees and rewards

This commit is contained in:
NikVolf 2016-12-14 13:20:09 +01:00
parent 9fc5583fa3
commit 91206defc1
2 changed files with 18 additions and 21 deletions

View File

@ -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::<u64>();
let spends = self.block.transactions.iter()
.skip(1)
.map(|tx| tx.raw.total_spends())
.sum::<u64>();
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 {

View File

@ -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)]