Fix mempool limiting for PrioritiseTransaction

Redo the feerate index to be based on mining score, rather than fee.

Update mempool_packages.py to test prioritisetransaction's effect on
package scores.
This commit is contained in:
Suhas Daftuar
2015-11-19 11:18:28 -05:00
committed by Suhas Daftuar
parent aeedd8a53b
commit eb306664e7
4 changed files with 78 additions and 46 deletions

View File

@@ -44,12 +44,12 @@ class CTxMemPool;
* ("descendant" transactions).
*
* When a new entry is added to the mempool, we update the descendant state
* (nCountWithDescendants, nSizeWithDescendants, and nFeesWithDescendants) for
* (nCountWithDescendants, nSizeWithDescendants, and nModFeesWithDescendants) for
* all ancestors of the newly added transaction.
*
* If updating the descendant state is skipped, we can mark the entry as
* "dirty", and set nSizeWithDescendants/nFeesWithDescendants to equal nTxSize/
* nTxFee. (This can potentially happen during a reorg, where we limit the
* "dirty", and set nSizeWithDescendants/nModFeesWithDescendants to equal nTxSize/
* nFee+feeDelta. (This can potentially happen during a reorg, where we limit the
* amount of work we're willing to do to avoid consuming too much CPU.)
*
*/
@@ -74,11 +74,11 @@ private:
// Information about descendants of this transaction that are in the
// mempool; if we remove this transaction we must remove all of these
// descendants as well. if nCountWithDescendants is 0, treat this entry as
// dirty, and nSizeWithDescendants and nFeesWithDescendants will not be
// dirty, and nSizeWithDescendants and nModFeesWithDescendants will not be
// correct.
uint64_t nCountWithDescendants; //! number of descendant transactions
uint64_t nSizeWithDescendants; //! ... and size
CAmount nFeesWithDescendants; //! ... and total fees (all including us)
CAmount nModFeesWithDescendants; //! ... and total fees (all including us)
public:
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
@@ -104,7 +104,8 @@ public:
// Adjusts the descendant state, if this entry is not dirty.
void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount);
// Updates the fee delta used for mining priority score
// Updates the fee delta used for mining priority score, and the
// modified fees with descendants.
void UpdateFeeDelta(int64_t feeDelta);
/** We can set the entry to be dirty if doing the full calculation of in-
@@ -116,7 +117,7 @@ public:
uint64_t GetCountWithDescendants() const { return nCountWithDescendants; }
uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
CAmount GetFeesWithDescendants() const { return nFeesWithDescendants; }
CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; }
bool GetSpendsCoinbase() const { return spendsCoinbase; }
};
@@ -163,27 +164,27 @@ struct mempoolentry_txid
}
};
/** \class CompareTxMemPoolEntryByFee
/** \class CompareTxMemPoolEntryByDescendantScore
*
* Sort an entry by max(feerate of entry's tx, feerate with all descendants).
* Sort an entry by max(score/size of entry's tx, score/size with all descendants).
*/
class CompareTxMemPoolEntryByFee
class CompareTxMemPoolEntryByDescendantScore
{
public:
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
{
bool fUseADescendants = UseDescendantFeeRate(a);
bool fUseBDescendants = UseDescendantFeeRate(b);
bool fUseADescendants = UseDescendantScore(a);
bool fUseBDescendants = UseDescendantScore(b);
double aFees = fUseADescendants ? a.GetFeesWithDescendants() : a.GetFee();
double aModFee = fUseADescendants ? a.GetModFeesWithDescendants() : a.GetModifiedFee();
double aSize = fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize();
double bFees = fUseBDescendants ? b.GetFeesWithDescendants() : b.GetFee();
double bModFee = fUseBDescendants ? b.GetModFeesWithDescendants() : b.GetModifiedFee();
double bSize = fUseBDescendants ? b.GetSizeWithDescendants() : b.GetTxSize();
// Avoid division by rewriting (a/b > c/d) as (a*d > c*b).
double f1 = aFees * bSize;
double f2 = aSize * bFees;
double f1 = aModFee * bSize;
double f2 = aSize * bModFee;
if (f1 == f2) {
return a.GetTime() >= b.GetTime();
@@ -191,11 +192,11 @@ public:
return f1 < f2;
}
// Calculate which feerate to use for an entry (avoiding division).
bool UseDescendantFeeRate(const CTxMemPoolEntry &a)
// Calculate which score to use for an entry (avoiding division).
bool UseDescendantScore(const CTxMemPoolEntry &a)
{
double f1 = (double)a.GetFee() * a.GetSizeWithDescendants();
double f2 = (double)a.GetFeesWithDescendants() * a.GetTxSize();
double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants();
double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize();
return f2 > f1;
}
};
@@ -350,7 +351,7 @@ public:
// sorted by fee rate
boost::multi_index::ordered_non_unique<
boost::multi_index::identity<CTxMemPoolEntry>,
CompareTxMemPoolEntryByFee
CompareTxMemPoolEntryByDescendantScore
>,
// sorted by entry time
boost::multi_index::ordered_non_unique<