Permalink
Browse files

Merge pull request #7008

c035306 Change GetPriority calculation. (Alex Morcos)
71f1d9f Modify variable names for entry height and priority (Alex Morcos)
5945819 Remove default arguments for CTxMemPoolEntry() (Alex Morcos)
  • Loading branch information...
laanwj committed Nov 30, 2015
2 parents 9b8fc6c + c035306 commit eb7741605b32c25893f687e19820dab114d04fe1
Showing with 42 additions and 21 deletions.
  1. +4 −2 src/coins.cpp
  2. +6 −2 src/coins.h
  3. +4 −3 src/main.cpp
  4. +1 −1 src/test/policyestimator_tests.cpp
  5. +7 −2 src/test/test_bitcoin.cpp
  6. +10 −7 src/txmempool.cpp
  7. +10 −4 src/txmempool.h
View
@@ -243,8 +243,9 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
return true;
}
-double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
+double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const
{
+ inChainInputValue = 0;
if (tx.IsCoinBase())
return 0.0;
double dResult = 0.0;
@@ -253,8 +254,9 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
const CCoins* coins = AccessCoins(txin.prevout.hash);
assert(coins);
if (!coins->IsAvailable(txin.prevout.n)) continue;
- if (coins->nHeight < nHeight) {
+ if (coins->nHeight <= nHeight) {
dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight);
+ inChainInputValue += coins->vout[txin.prevout.n].nValue;
}
}
return tx.ComputePriority(dResult);
View
@@ -456,8 +456,12 @@ class CCoinsViewCache : public CCoinsViewBacked
//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
bool HaveInputs(const CTransaction& tx) const;
- //! Return priority of tx at height nHeight
- double GetPriority(const CTransaction &tx, int nHeight) 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.
+ */
+ double GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const;
const CTxOut &GetOutputFor(const CTxIn& input) const;
View
@@ -950,9 +950,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
CAmount nValueOut = tx.GetValueOut();
CAmount nFees = nValueIn-nValueOut;
- double dPriority = view.GetPriority(tx, chainActive.Height());
+ CAmount inChainInputValue;
+ double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue);
- CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx));
+ CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue);
unsigned int nSize = entry.GetTxSize();
// Don't accept it if it can't get into a block
@@ -964,7 +965,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee));
- } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
+ } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
// Require that free transactions have sufficient priority to be mined in the next block.
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
}
@@ -196,7 +196,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
// Test that if the mempool is limited, estimateSmartFee won't return a value below the mempool min fee
// and that estimateSmartPriority returns essentially an infinite value
- mpool.addUnchecked(tx.GetHash(), CTxMemPoolEntry(tx, feeV[0][5], GetTime(), priV[1][5], blocknum, mpool.HasNoInputsOf(tx)));
+ mpool.addUnchecked(tx.GetHash(), entry.Fee(feeV[0][5]).Time(GetTime()).Priority(priV[1][5]).Height(blocknum).FromTx(tx, &mpool));
// evict that transaction which should set a mempool min fee of minRelayTxFee + feeV[0][5]
mpool.TrimToSize(1);
BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[0][5]);
@@ -144,8 +144,13 @@ TestChain100Setup::~TestChain100Setup()
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) {
- return CTxMemPoolEntry(tx, nFee, nTime, dPriority, nHeight,
- pool ? pool->HasNoInputsOf(tx) : hadNoDependencies);
+ CTransaction txn(tx);
+ bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies;
+ // Hack to assume either its completely dependent on other mempool txs or not at all
+ CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;
+
+ return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
+ hasNoDependencies, inChainValue);
}
void Shutdown(void* parg)
View
@@ -19,10 +19,10 @@
using namespace std;
CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
- int64_t _nTime, double _dPriority,
- unsigned int _nHeight, bool poolHasNoInputsOf):
- tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight),
- hadNoDependencies(poolHasNoInputsOf)
+ int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
+ bool poolHasNoInputsOf, CAmount _inChainInputValue):
+ tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
+ hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue)
{
nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
nModSize = tx.CalculateModifiedSize(nTxSize);
@@ -31,6 +31,8 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
nCountWithDescendants = 1;
nSizeWithDescendants = nTxSize;
nFeesWithDescendants = nFee;
+ CAmount nValueIn = tx.GetValueOut()+nFee;
+ assert(inChainInputValue <= nValueIn);
}
CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
@@ -41,9 +43,10 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
double
CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
{
- CAmount nValueIn = tx.GetValueOut()+nFee;
- double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize;
- double dResult = dPriority + deltaPriority;
+ double deltaPriority = ((double)(currentHeight-entryHeight)*inChainInputValue)/nModSize;
+ double dResult = entryPriority + deltaPriority;
+ if (dResult < 0) // This should only happen if it was called with a height below entry height
+ dResult = 0;
return dResult;
}
View
@@ -63,9 +63,10 @@ class CTxMemPoolEntry
size_t nModSize; //! ... and modified size for priority
size_t nUsageSize; //! ... and total memory usage
int64_t nTime; //! Local time when entering the mempool
- double dPriority; //! Priority when entering the mempool
- unsigned int nHeight; //! Chain height when entering the mempool
+ double entryPriority; //! Priority when entering the mempool
+ unsigned int entryHeight; //! Chain height when entering the mempool
bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool
+ CAmount inChainInputValue; //! Sum of all txin values that are already in blockchain
// Information about descendants of this transaction that are in the
// mempool; if we remove this transaction we must remove all of these
@@ -78,15 +79,20 @@ class CTxMemPoolEntry
public:
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
- int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false);
+ int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
+ bool poolHasNoInputsOf, CAmount _inChainInputValue);
CTxMemPoolEntry(const CTxMemPoolEntry& other);
const CTransaction& GetTx() const { return this->tx; }
+ /**
+ * Fast calculation of lower bound of current priority as update
+ * from entry priority. Only inputs that were originally in-chain will age.
+ */
double GetPriority(unsigned int currentHeight) const;
const CAmount& GetFee() const { return nFee; }
size_t GetTxSize() const { return nTxSize; }
int64_t GetTime() const { return nTime; }
- unsigned int GetHeight() const { return nHeight; }
+ unsigned int GetHeight() const { return entryHeight; }
bool WasClearAtEntry() const { return hadNoDependencies; }
size_t DynamicMemoryUsage() const { return nUsageSize; }

0 comments on commit eb77416

Please sign in to comment.