Skip to content

Commit eb77416

Browse files
committed
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)
2 parents 9b8fc6c + c035306 commit eb77416

File tree

7 files changed

+42
-21
lines changed

7 files changed

+42
-21
lines changed

src/coins.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,9 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
243243
return true;
244244
}
245245

246-
double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
246+
double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const
247247
{
248+
inChainInputValue = 0;
248249
if (tx.IsCoinBase())
249250
return 0.0;
250251
double dResult = 0.0;
@@ -253,8 +254,9 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
253254
const CCoins* coins = AccessCoins(txin.prevout.hash);
254255
assert(coins);
255256
if (!coins->IsAvailable(txin.prevout.n)) continue;
256-
if (coins->nHeight < nHeight) {
257+
if (coins->nHeight <= nHeight) {
257258
dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight);
259+
inChainInputValue += coins->vout[txin.prevout.n].nValue;
258260
}
259261
}
260262
return tx.ComputePriority(dResult);

src/coins.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,12 @@ class CCoinsViewCache : public CCoinsViewBacked
456456
//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
457457
bool HaveInputs(const CTransaction& tx) const;
458458

459-
//! Return priority of tx at height nHeight
460-
double GetPriority(const CTransaction &tx, int nHeight) const;
459+
/**
460+
* Return priority of tx at height nHeight. Also calculate the sum of the values of the inputs
461+
* that are already in the chain. These are the inputs that will age and increase priority as
462+
* new blocks are added to the chain.
463+
*/
464+
double GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const;
461465

462466
const CTxOut &GetOutputFor(const CTxIn& input) const;
463467

src/main.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -950,9 +950,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
950950

951951
CAmount nValueOut = tx.GetValueOut();
952952
CAmount nFees = nValueIn-nValueOut;
953-
double dPriority = view.GetPriority(tx, chainActive.Height());
953+
CAmount inChainInputValue;
954+
double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue);
954955

955-
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx));
956+
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue);
956957
unsigned int nSize = entry.GetTxSize();
957958

958959
// Don't accept it if it can't get into a block
@@ -964,7 +965,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
964965
CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
965966
if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
966967
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee));
967-
} else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
968+
} else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
968969
// Require that free transactions have sufficient priority to be mined in the next block.
969970
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
970971
}

src/test/policyestimator_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
196196

197197
// Test that if the mempool is limited, estimateSmartFee won't return a value below the mempool min fee
198198
// and that estimateSmartPriority returns essentially an infinite value
199-
mpool.addUnchecked(tx.GetHash(), CTxMemPoolEntry(tx, feeV[0][5], GetTime(), priV[1][5], blocknum, mpool.HasNoInputsOf(tx)));
199+
mpool.addUnchecked(tx.GetHash(), entry.Fee(feeV[0][5]).Time(GetTime()).Priority(priV[1][5]).Height(blocknum).FromTx(tx, &mpool));
200200
// evict that transaction which should set a mempool min fee of minRelayTxFee + feeV[0][5]
201201
mpool.TrimToSize(1);
202202
BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[0][5]);

src/test/test_bitcoin.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,13 @@ TestChain100Setup::~TestChain100Setup()
144144

145145

146146
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) {
147-
return CTxMemPoolEntry(tx, nFee, nTime, dPriority, nHeight,
148-
pool ? pool->HasNoInputsOf(tx) : hadNoDependencies);
147+
CTransaction txn(tx);
148+
bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies;
149+
// Hack to assume either its completely dependent on other mempool txs or not at all
150+
CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;
151+
152+
return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
153+
hasNoDependencies, inChainValue);
149154
}
150155

151156
void Shutdown(void* parg)

src/txmempool.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
using namespace std;
2020

2121
CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
22-
int64_t _nTime, double _dPriority,
23-
unsigned int _nHeight, bool poolHasNoInputsOf):
24-
tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight),
25-
hadNoDependencies(poolHasNoInputsOf)
22+
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
23+
bool poolHasNoInputsOf, CAmount _inChainInputValue):
24+
tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
25+
hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue)
2626
{
2727
nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
2828
nModSize = tx.CalculateModifiedSize(nTxSize);
@@ -31,6 +31,8 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
3131
nCountWithDescendants = 1;
3232
nSizeWithDescendants = nTxSize;
3333
nFeesWithDescendants = nFee;
34+
CAmount nValueIn = tx.GetValueOut()+nFee;
35+
assert(inChainInputValue <= nValueIn);
3436
}
3537

3638
CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
@@ -41,9 +43,10 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
4143
double
4244
CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
4345
{
44-
CAmount nValueIn = tx.GetValueOut()+nFee;
45-
double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize;
46-
double dResult = dPriority + deltaPriority;
46+
double deltaPriority = ((double)(currentHeight-entryHeight)*inChainInputValue)/nModSize;
47+
double dResult = entryPriority + deltaPriority;
48+
if (dResult < 0) // This should only happen if it was called with a height below entry height
49+
dResult = 0;
4750
return dResult;
4851
}
4952

src/txmempool.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ class CTxMemPoolEntry
6363
size_t nModSize; //! ... and modified size for priority
6464
size_t nUsageSize; //! ... and total memory usage
6565
int64_t nTime; //! Local time when entering the mempool
66-
double dPriority; //! Priority when entering the mempool
67-
unsigned int nHeight; //! Chain height when entering the mempool
66+
double entryPriority; //! Priority when entering the mempool
67+
unsigned int entryHeight; //! Chain height when entering the mempool
6868
bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool
69+
CAmount inChainInputValue; //! Sum of all txin values that are already in blockchain
6970

7071
// Information about descendants of this transaction that are in the
7172
// mempool; if we remove this transaction we must remove all of these
@@ -78,15 +79,20 @@ class CTxMemPoolEntry
7879

7980
public:
8081
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
81-
int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false);
82+
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
83+
bool poolHasNoInputsOf, CAmount _inChainInputValue);
8284
CTxMemPoolEntry(const CTxMemPoolEntry& other);
8385

8486
const CTransaction& GetTx() const { return this->tx; }
87+
/**
88+
* Fast calculation of lower bound of current priority as update
89+
* from entry priority. Only inputs that were originally in-chain will age.
90+
*/
8591
double GetPriority(unsigned int currentHeight) const;
8692
const CAmount& GetFee() const { return nFee; }
8793
size_t GetTxSize() const { return nTxSize; }
8894
int64_t GetTime() const { return nTime; }
89-
unsigned int GetHeight() const { return nHeight; }
95+
unsigned int GetHeight() const { return entryHeight; }
9096
bool WasClearAtEntry() const { return hadNoDependencies; }
9197
size_t DynamicMemoryUsage() const { return nUsageSize; }
9298

0 commit comments

Comments
 (0)