From f512cf7c7b8a5c481017d6d9fdbde1f689dccf37 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Mon, 4 Jan 2016 06:02:01 -0700 Subject: [PATCH] Added value balance consensus enforcement for pours. --- src/coins.cpp | 2 ++ src/main.cpp | 5 +++++ src/primitives/transaction.cpp | 24 ++++++++++++++++++++++++ src/primitives/transaction.h | 3 +++ 4 files changed, 34 insertions(+) diff --git a/src/coins.cpp b/src/coins.cpp index de826380d..9f79a6e2b 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -382,6 +382,8 @@ CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const for (unsigned int i = 0; i < tx.vin.size(); i++) nResult += GetOutputFor(tx.vin[i]).nValue; + nResult += tx.GetPourValueIn(); + return nResult; } diff --git a/src/main.cpp b/src/main.cpp index 703848580..544a34fbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1533,6 +1533,11 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi } + nValueIn += tx.GetPourValueIn(); + if (!MoneyRange(nValueIn)) + return state.DoS(100, error("CheckInputs(): vpub_old values out of range"), + REJECT_INVALID, "bad-txns-inputvalues-outofrange"); + if (nValueIn < tx.GetValueOut()) return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s)", tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())), diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 4bf1faeab..0feceaa1a 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -178,9 +178,33 @@ CAmount CTransaction::GetValueOut() const if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut)) throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); } + + for (std::vector::const_iterator it(vpour.begin()); it != vpour.end(); ++it) + { + // NB: vpub_old "takes" money from the value pool just as outputs do + nValueOut += it->vpub_old; + + if (!MoneyRange(it->vpub_old) || !MoneyRange(nValueOut)) + throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); + } return nValueOut; } +CAmount CTransaction::GetPourValueIn() const +{ + CAmount nValue = 0; + for (std::vector::const_iterator it(vpour.begin()); it != vpour.end(); ++it) + { + // NB: vpub_old "gives" money to the value pool just as inputs do + nValue += it->vpub_new; + + if (!MoneyRange(it->vpub_new) || !MoneyRange(nValue)) + throw std::runtime_error("CTransaction::GetPourValueIn(): value out of range"); + } + + return nValue; +} + double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const { nTxSize = CalculateModifiedSize(nTxSize); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 9927d85bc..a7c54be10 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -346,6 +346,9 @@ public: // GetValueIn() is a method on CCoinsViewCache, because // inputs must be known to compute value in. + // Return sum of pour vpub_new + CAmount GetPourValueIn() const; + // Compute priority, given priority of inputs and (optionally) tx size double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const;