diff --git a/src/coins.h b/src/coins.h --- a/src/coins.h +++ b/src/coins.h @@ -270,8 +270,9 @@ * values of the inputs that are already in the chain. These are the inputs * that will age and increase priority as new blocks are added to the chain. */ - double GetPriority(const CTransaction &tx, int nHeight, - Amount &inChainInputValue) const; + Amount GetTransactionInputValue(const CTransaction &tx, int nHeight) const; + + double GetCoinDaysDestroyed(const CTransaction &tx, int nHeight) const; const CTxOut &GetOutputFor(const CTxIn &input) const; diff --git a/src/coins.cpp b/src/coins.cpp --- a/src/coins.cpp +++ b/src/coins.cpp @@ -298,25 +298,43 @@ return true; } -double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, - Amount &inChainInputValue) const { - inChainInputValue = Amount(0); +Amount CCoinsViewCache::GetTransactionInputValue(const CTransaction &tx, + int nHeight) const { + Amount inChainInputValue(0); + if (tx.IsCoinBase()) { - return 0.0; + return inChainInputValue; } - double dResult = 0.0; + for (const CTxIn &txin : tx.vin) { const Coin &coin = AccessCoin(txin.prevout); - if (coin.IsSpent()) { + if (coin.IsSpent() || int64_t(coin.GetHeight()) > nHeight) { continue; } - if (int64_t(coin.GetHeight()) <= nHeight) { - dResult += double(coin.GetTxOut().nValue.GetSatoshis()) * - (nHeight - coin.GetHeight()); - inChainInputValue += coin.GetTxOut().nValue; + inChainInputValue += coin.GetTxOut().nValue; + } + + return inChainInputValue; +} + +double CCoinsViewCache::GetCoinDaysDestroyed(const CTransaction &tx, + int nHeight) const { + double coinDaysDestroyed = 0.0; + + if (tx.IsCoinBase()) { + return coinDaysDestroyed; + } + + for (const CTxIn &txin : tx.vin) { + const Coin &coin = AccessCoin(txin.prevout); + if (coin.IsSpent() || int64_t(coin.GetHeight()) > nHeight) { + continue; } + coinDaysDestroyed += double(coin.GetTxOut().nValue.GetSatoshis()) * + (nHeight - coin.GetHeight()); } - return tx.ComputePriority(dResult); + + return coinDaysDestroyed; } // TODO: merge with similar definition in undo.h. diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -102,12 +102,12 @@ return nValueOut; } -double CTransaction::ComputePriority(double dPriorityInputs, +double CTransaction::ComputePriority(double coinDaysDestroyed, unsigned int nTxSize) const { nTxSize = CalculateModifiedSize(nTxSize); if (nTxSize == 0) return 0.0; - return dPriorityInputs / nTxSize; + return coinDaysDestroyed / nTxSize; } unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const { diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -779,9 +779,10 @@ double nPriorityDummy = 0; pool.ApplyDeltas(txid, nPriorityDummy, nModifiedFees); - Amount inChainInputValue; - double dPriority = - view.GetPriority(tx, chainActive.Height(), inChainInputValue); + Amount inChainInputValue = + view.GetTransactionInputValue(tx, chainActive.Height()); + double cdd = view.GetCoinDaysDestroyed(tx, chainActive.Height()); + double dPriority = tx.ComputePriority(cdd); // Keep track of transactions that spend a coinbase, which we re-scan // during reorgs to ensure COINBASE_MATURITY is still met.