Add a score index to the mempool.
The score index is meant to represent the order of priority for being included in a block for miners. Initially this is set to the transactions modified (by any feeDelta) fee rate. Index improvements and unit tests by sdaftuar.
This commit is contained in:
@@ -69,6 +69,7 @@ private:
|
||||
CAmount inChainInputValue; //! Sum of all txin values that are already in blockchain
|
||||
bool spendsCoinbase; //! keep track of transactions that spend a coinbase
|
||||
unsigned int sigOpCount; //! Legacy sig ops plus P2SH sig op count
|
||||
int64_t feeDelta; //! Used for determining the priority of the transaction for mining in a block
|
||||
|
||||
// Information about descendants of this transaction that are in the
|
||||
// mempool; if we remove this transaction we must remove all of these
|
||||
@@ -98,10 +99,13 @@ public:
|
||||
unsigned int GetHeight() const { return entryHeight; }
|
||||
bool WasClearAtEntry() const { return hadNoDependencies; }
|
||||
unsigned int GetSigOpCount() const { return sigOpCount; }
|
||||
int64_t GetModifiedFee() const { return nFee + feeDelta; }
|
||||
size_t DynamicMemoryUsage() const { return nUsageSize; }
|
||||
|
||||
// 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
|
||||
void UpdateFeeDelta(int64_t feeDelta);
|
||||
|
||||
/** We can set the entry to be dirty if doing the full calculation of in-
|
||||
* mempool descendants will be too expensive, which can potentially happen
|
||||
@@ -139,6 +143,16 @@ struct set_dirty
|
||||
{ e.SetDirty(); }
|
||||
};
|
||||
|
||||
struct update_fee_delta
|
||||
{
|
||||
update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { }
|
||||
|
||||
void operator() (CTxMemPoolEntry &e) { e.UpdateFeeDelta(feeDelta); }
|
||||
|
||||
private:
|
||||
int64_t feeDelta;
|
||||
};
|
||||
|
||||
// extracts a TxMemPoolEntry's transaction hash
|
||||
struct mempoolentry_txid
|
||||
{
|
||||
@@ -186,6 +200,24 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** \class CompareTxMemPoolEntryByScore
|
||||
*
|
||||
* Sort by score of entry ((fee+delta)/size) in descending order
|
||||
*/
|
||||
class CompareTxMemPoolEntryByScore
|
||||
{
|
||||
public:
|
||||
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
|
||||
{
|
||||
double f1 = (double)a.GetModifiedFee() * b.GetTxSize();
|
||||
double f2 = (double)b.GetModifiedFee() * a.GetTxSize();
|
||||
if (f1 == f2) {
|
||||
return b.GetTx().GetHash() < a.GetTx().GetHash();
|
||||
}
|
||||
return f1 > f2;
|
||||
}
|
||||
};
|
||||
|
||||
class CompareTxMemPoolEntryByEntryTime
|
||||
{
|
||||
public:
|
||||
@@ -223,10 +255,11 @@ public:
|
||||
*
|
||||
* CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping:
|
||||
*
|
||||
* mapTx is a boost::multi_index that sorts the mempool on 3 criteria:
|
||||
* mapTx is a boost::multi_index that sorts the mempool on 4 criteria:
|
||||
* - transaction hash
|
||||
* - feerate [we use max(feerate of tx, feerate of tx with all descendants)]
|
||||
* - time in mempool
|
||||
* - mining score (feerate modified by any fee deltas from PrioritiseTransaction)
|
||||
*
|
||||
* Note: the term "descendant" refers to in-mempool transactions that depend on
|
||||
* this one, while "ancestor" refers to in-mempool transactions that a given
|
||||
@@ -323,6 +356,11 @@ public:
|
||||
boost::multi_index::ordered_non_unique<
|
||||
boost::multi_index::identity<CTxMemPoolEntry>,
|
||||
CompareTxMemPoolEntryByEntryTime
|
||||
>,
|
||||
// sorted by score (for mining prioritization)
|
||||
boost::multi_index::ordered_unique<
|
||||
boost::multi_index::identity<CTxMemPoolEntry>,
|
||||
CompareTxMemPoolEntryByScore
|
||||
>
|
||||
>
|
||||
> indexed_transaction_set;
|
||||
|
||||
Reference in New Issue
Block a user