mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-10 10:52:31 -05:00
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)
This commit is contained in:
commit
eb7741605b
7 changed files with 42 additions and 21 deletions
|
@ -243,8 +243,9 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
|
||||||
return true;
|
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())
|
if (tx.IsCoinBase())
|
||||||
return 0.0;
|
return 0.0;
|
||||||
double dResult = 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);
|
const CCoins* coins = AccessCoins(txin.prevout.hash);
|
||||||
assert(coins);
|
assert(coins);
|
||||||
if (!coins->IsAvailable(txin.prevout.n)) continue;
|
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);
|
dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight);
|
||||||
|
inChainInputValue += coins->vout[txin.prevout.n].nValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tx.ComputePriority(dResult);
|
return tx.ComputePriority(dResult);
|
||||||
|
|
|
@ -456,8 +456,12 @@ public:
|
||||||
//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
|
//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
|
||||||
bool HaveInputs(const CTransaction& tx) const;
|
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;
|
const CTxOut &GetOutputFor(const CTxIn& input) const;
|
||||||
|
|
||||||
|
|
|
@ -950,9 +950,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||||
|
|
||||||
CAmount nValueOut = tx.GetValueOut();
|
CAmount nValueOut = tx.GetValueOut();
|
||||||
CAmount nFees = nValueIn-nValueOut;
|
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();
|
unsigned int nSize = entry.GetTxSize();
|
||||||
|
|
||||||
// Don't accept it if it can't get into a block
|
// 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);
|
CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
|
||||||
if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
|
if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
|
||||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", 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.
|
// Require that free transactions have sufficient priority to be mined in the next block.
|
||||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
|
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
|
// 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
|
// 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]
|
// evict that transaction which should set a mempool min fee of minRelayTxFee + feeV[0][5]
|
||||||
mpool.TrimToSize(1);
|
mpool.TrimToSize(1);
|
||||||
BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[0][5]);
|
BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[0][5]);
|
||||||
|
|
|
@ -144,8 +144,13 @@ TestChain100Setup::~TestChain100Setup()
|
||||||
|
|
||||||
|
|
||||||
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) {
|
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) {
|
||||||
return CTxMemPoolEntry(tx, nFee, nTime, dPriority, nHeight,
|
CTransaction txn(tx);
|
||||||
pool ? pool->HasNoInputsOf(tx) : hadNoDependencies);
|
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)
|
void Shutdown(void* parg)
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
|
CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
|
||||||
int64_t _nTime, double _dPriority,
|
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
|
||||||
unsigned int _nHeight, bool poolHasNoInputsOf):
|
bool poolHasNoInputsOf, CAmount _inChainInputValue):
|
||||||
tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight),
|
tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
|
||||||
hadNoDependencies(poolHasNoInputsOf)
|
hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue)
|
||||||
{
|
{
|
||||||
nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
nModSize = tx.CalculateModifiedSize(nTxSize);
|
nModSize = tx.CalculateModifiedSize(nTxSize);
|
||||||
|
@ -31,6 +31,8 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
|
||||||
nCountWithDescendants = 1;
|
nCountWithDescendants = 1;
|
||||||
nSizeWithDescendants = nTxSize;
|
nSizeWithDescendants = nTxSize;
|
||||||
nFeesWithDescendants = nFee;
|
nFeesWithDescendants = nFee;
|
||||||
|
CAmount nValueIn = tx.GetValueOut()+nFee;
|
||||||
|
assert(inChainInputValue <= nValueIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
|
CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
|
||||||
|
@ -41,9 +43,10 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
|
||||||
double
|
double
|
||||||
CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
|
CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
|
||||||
{
|
{
|
||||||
CAmount nValueIn = tx.GetValueOut()+nFee;
|
double deltaPriority = ((double)(currentHeight-entryHeight)*inChainInputValue)/nModSize;
|
||||||
double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize;
|
double dResult = entryPriority + deltaPriority;
|
||||||
double dResult = dPriority + deltaPriority;
|
if (dResult < 0) // This should only happen if it was called with a height below entry height
|
||||||
|
dResult = 0;
|
||||||
return dResult;
|
return dResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,9 +63,10 @@ private:
|
||||||
size_t nModSize; //! ... and modified size for priority
|
size_t nModSize; //! ... and modified size for priority
|
||||||
size_t nUsageSize; //! ... and total memory usage
|
size_t nUsageSize; //! ... and total memory usage
|
||||||
int64_t nTime; //! Local time when entering the mempool
|
int64_t nTime; //! Local time when entering the mempool
|
||||||
double dPriority; //! Priority when entering the mempool
|
double entryPriority; //! Priority when entering the mempool
|
||||||
unsigned int nHeight; //! Chain height 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
|
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
|
// Information about descendants of this transaction that are in the
|
||||||
// mempool; if we remove this transaction we must remove all of these
|
// mempool; if we remove this transaction we must remove all of these
|
||||||
|
@ -78,15 +79,20 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
|
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);
|
CTxMemPoolEntry(const CTxMemPoolEntry& other);
|
||||||
|
|
||||||
const CTransaction& GetTx() const { return this->tx; }
|
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;
|
double GetPriority(unsigned int currentHeight) const;
|
||||||
const CAmount& GetFee() const { return nFee; }
|
const CAmount& GetFee() const { return nFee; }
|
||||||
size_t GetTxSize() const { return nTxSize; }
|
size_t GetTxSize() const { return nTxSize; }
|
||||||
int64_t GetTime() const { return nTime; }
|
int64_t GetTime() const { return nTime; }
|
||||||
unsigned int GetHeight() const { return nHeight; }
|
unsigned int GetHeight() const { return entryHeight; }
|
||||||
bool WasClearAtEntry() const { return hadNoDependencies; }
|
bool WasClearAtEntry() const { return hadNoDependencies; }
|
||||||
size_t DynamicMemoryUsage() const { return nUsageSize; }
|
size_t DynamicMemoryUsage() const { return nUsageSize; }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue