diff --git a/src/coins.h b/src/coins.h --- a/src/coins.h +++ b/src/coins.h @@ -266,12 +266,18 @@ bool HaveInputs(const CTransaction &tx) const; /** - * Return priority of tx at height nHeight. Also calculate the sum of the - * 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. + * Return "valid" tx input value + * + * TODO: This should be able to be replaced with GetValueIn, but there are + * some additional checks in this code that need to be verified as + * removable. + */ + Amount GetChainValidTxInputValue(const CTransaction &tx, int nHeight) const; + + /** + * Return number of coins*blocks destroyed in this transaction. */ - double GetPriority(const CTransaction &tx, int nHeight, - Amount &inChainInputValue) const; + double GetCoinBlocksDestroyed(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,41 @@ return true; } -double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, - Amount &inChainInputValue) const { - inChainInputValue = Amount(0); +Amount CCoinsViewCache::GetChainValidTxInputValue(const CTransaction &tx, + int nHeight) const { if (tx.IsCoinBase()) { - return 0.0; + return Amount(0); } - double dResult = 0.0; + + Amount inChainInputValue(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::GetCoinBlocksDestroyed(const CTransaction &tx, + int nHeight) const { + if (tx.IsCoinBase()) { + return 0.0; + } + + double coinBlocksDestroyed = 0.0; + for (const CTxIn &txin : tx.vin) { + const Coin &coin = AccessCoin(txin.prevout); + if (coin.IsSpent() || int64_t(coin.GetHeight()) > nHeight) { + continue; } + coinBlocksDestroyed += double(coin.GetTxOut().nValue.GetSatoshis()) * + (nHeight - coin.GetHeight()); } - return tx.ComputePriority(dResult); + + return coinBlocksDestroyed; } // 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 coinBlocksDestroyed, unsigned int nTxSize) const { nTxSize = CalculateModifiedSize(nTxSize); if (nTxSize == 0) return 0.0; - return dPriorityInputs / nTxSize; + return coinBlocksDestroyed / 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 txValidInputValue = + view.GetChainValidTxInputValue(tx, chainActive.Height()); + double cbd = view.GetCoinBlocksDestroyed(tx, chainActive.Height()); + double dPriority = tx.ComputePriority(cbd); // Keep track of transactions that spend a coinbase, which we re-scan // during reorgs to ensure COINBASE_MATURITY is still met. @@ -795,7 +796,7 @@ } CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, dPriority, - chainActive.Height(), inChainInputValue, + chainActive.Height(), txValidInputValue, fSpendsCoinbase, nSigOpsCount, lp); unsigned int nSize = entry.GetTxSize();