Browse Source

[mining] Remove -blockprioritysize.

Remove ability of mining code to fill part of a block with transactions sorted by coin age.
0.15
Alex Morcos 8 years ago
parent
commit
272b25a6a9
  1. 4
      qa/rpc-tests/bip68-sequence.py
  2. 4
      qa/rpc-tests/smartfees.py
  3. 1
      src/init.cpp
  4. 153
      src/miner.cpp
  5. 12
      src/miner.h
  6. 2
      src/policy/policy.h
  7. 1
      src/test/miner_tests.cpp
  8. 13
      src/txmempool.h

4
qa/rpc-tests/bip68-sequence.py

@ -24,8 +24,8 @@ class BIP68Test(BitcoinTestFramework):
def setup_network(self): def setup_network(self):
self.nodes = [] self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-blockprioritysize=0"])) self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"]))
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-blockprioritysize=0", "-acceptnonstdtxn=0"])) self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-acceptnonstdtxn=0"]))
self.is_network_split = False self.is_network_split = False
self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"] self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[0], 1)

4
qa/rpc-tests/smartfees.py

@ -193,13 +193,13 @@ class EstimateFeeTest(BitcoinTestFramework):
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes, # NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
# (17k is room enough for 110 or so transactions) # (17k is room enough for 110 or so transactions)
self.nodes.append(start_node(1, self.options.tmpdir, self.nodes.append(start_node(1, self.options.tmpdir,
["-blockprioritysize=1500", "-blockmaxsize=17000", ["-blockmaxsize=17000",
"-maxorphantx=1000", "-debug=estimatefee"])) "-maxorphantx=1000", "-debug=estimatefee"]))
connect_nodes(self.nodes[1], 0) connect_nodes(self.nodes[1], 0)
# Node2 is a stingy miner, that # Node2 is a stingy miner, that
# produces too small blocks (room for only 55 or so transactions) # produces too small blocks (room for only 55 or so transactions)
node2args = ["-blockprioritysize=0", "-blockmaxsize=8000", "-maxorphantx=1000"] node2args = ["-blockmaxsize=8000", "-maxorphantx=1000"]
self.nodes.append(start_node(2, self.options.tmpdir, node2args)) self.nodes.append(start_node(2, self.options.tmpdir, node2args))
connect_nodes(self.nodes[0], 2) connect_nodes(self.nodes[0], 2)

1
src/init.cpp

@ -476,7 +476,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageGroup(_("Block creation options:")); strUsage += HelpMessageGroup(_("Block creation options:"));
strUsage += HelpMessageOpt("-blockmaxweight=<n>", strprintf(_("Set maximum BIP141 block weight (default: %d)"), DEFAULT_BLOCK_MAX_WEIGHT)); strUsage += HelpMessageOpt("-blockmaxweight=<n>", strprintf(_("Set maximum BIP141 block weight (default: %d)"), DEFAULT_BLOCK_MAX_WEIGHT));
strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
strUsage += HelpMessageOpt("-blockmintxfee=<amt>", strprintf(_("Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE))); strUsage += HelpMessageOpt("-blockmintxfee=<amt>", strprintf(_("Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)));
if (showDebug) if (showDebug)
strUsage += HelpMessageOpt("-blockversion=<n>", "Override block version to test forking scenarios"); strUsage += HelpMessageOpt("-blockversion=<n>", "Override block version to test forking scenarios");

153
src/miner.cpp

@ -39,8 +39,8 @@
// //
// Unconfirmed transactions in the memory pool often depend on other // Unconfirmed transactions in the memory pool often depend on other
// transactions in the memory pool. When we select transactions from the // transactions in the memory pool. When we select transactions from the
// pool, we select by highest priority or fee rate, so we might consider // pool, we select by highest fee rate of a transaction combined with all
// transactions that depend on transactions that aren't yet in the block. // its ancestors.
uint64_t nLastBlockTx = 0; uint64_t nLastBlockTx = 0;
uint64_t nLastBlockSize = 0; uint64_t nLastBlockSize = 0;
@ -122,9 +122,6 @@ void BlockAssembler::resetBlock()
// These counters do not include coinbase tx // These counters do not include coinbase tx
nBlockTx = 0; nBlockTx = 0;
nFees = 0; nFees = 0;
lastFewTxs = 0;
blockFinished = false;
} }
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
@ -167,7 +164,6 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
// transaction (which in most cases can be a no-op). // transaction (which in most cases can be a no-op).
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()); fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
addPriorityTxs();
addPackageTxs(); addPackageTxs();
nLastBlockTx = nBlockTx; nLastBlockTx = nBlockTx;
@ -204,17 +200,6 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
return std::move(pblocktemplate); return std::move(pblocktemplate);
} }
bool BlockAssembler::isStillDependent(CTxMemPool::txiter iter)
{
BOOST_FOREACH(CTxMemPool::txiter parent, mempool.GetMemPoolParents(iter))
{
if (!inBlock.count(parent)) {
return true;
}
}
return false;
}
void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet)
{ {
for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) { for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) {
@ -262,58 +247,6 @@ bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& packa
return true; return true;
} }
bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter)
{
if (nBlockWeight + iter->GetTxWeight() >= nBlockMaxWeight) {
// If the block is so close to full that no more txs will fit
// or if we've tried more than 50 times to fill remaining space
// then flag that the block is finished
if (nBlockWeight > nBlockMaxWeight - 400 || lastFewTxs > 50) {
blockFinished = true;
return false;
}
// Once we're within 4000 weight of a full block, only look at 50 more txs
// to try to fill the remaining space.
if (nBlockWeight > nBlockMaxWeight - 4000) {
lastFewTxs++;
}
return false;
}
if (fNeedSizeAccounting) {
if (nBlockSize + ::GetSerializeSize(iter->GetTx(), SER_NETWORK, PROTOCOL_VERSION) >= nBlockMaxSize) {
if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) {
blockFinished = true;
return false;
}
if (nBlockSize > nBlockMaxSize - 1000) {
lastFewTxs++;
}
return false;
}
}
if (nBlockSigOpsCost + iter->GetSigOpCost() >= MAX_BLOCK_SIGOPS_COST) {
// If the block has room for no more sig ops then
// flag that the block is finished
if (nBlockSigOpsCost > MAX_BLOCK_SIGOPS_COST - 8) {
blockFinished = true;
return false;
}
// Otherwise attempt to find another tx with fewer sigops
// to put in the block.
return false;
}
// Must check that lock times are still valid
// This can be removed once MTP is always enforced
// as long as reorgs keep the mempool consistent.
if (!IsFinalTx(iter->GetTx(), nHeight, nLockTimeCutoff))
return false;
return true;
}
void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
{ {
pblock->vtx.emplace_back(iter->GetSharedTx()); pblock->vtx.emplace_back(iter->GetSharedTx());
@ -512,88 +445,6 @@ void BlockAssembler::addPackageTxs()
} }
} }
void BlockAssembler::addPriorityTxs()
{
// How much of the block should be dedicated to high-priority transactions,
// included regardless of the fees they pay
unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE);
nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize);
if (nBlockPrioritySize == 0) {
return;
}
bool fSizeAccounting = fNeedSizeAccounting;
fNeedSizeAccounting = true;
// This vector will be sorted into a priority queue:
std::vector<TxCoinAgePriority> vecPriority;
TxCoinAgePriorityCompare pricomparer;
std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash> waitPriMap;
typedef std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash>::iterator waitPriIter;
double actualPriority = -1;
vecPriority.reserve(mempool.mapTx.size());
for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
mi != mempool.mapTx.end(); ++mi)
{
double dPriority = mi->GetPriority(nHeight);
CAmount dummy;
mempool.ApplyDeltas(mi->GetTx().GetHash(), dPriority, dummy);
vecPriority.push_back(TxCoinAgePriority(dPriority, mi));
}
std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
CTxMemPool::txiter iter;
while (!vecPriority.empty() && !blockFinished) { // add a tx from priority queue to fill the blockprioritysize
iter = vecPriority.front().second;
actualPriority = vecPriority.front().first;
std::pop_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
vecPriority.pop_back();
// If tx already in block, skip
if (inBlock.count(iter)) {
assert(false); // shouldn't happen for priority txs
continue;
}
// cannot accept witness transactions into a non-witness block
if (!fIncludeWitness && iter->GetTx().HasWitness())
continue;
// If tx is dependent on other mempool txs which haven't yet been included
// then put it in the waitSet
if (isStillDependent(iter)) {
waitPriMap.insert(std::make_pair(iter, actualPriority));
continue;
}
// If this tx fits in the block add it, otherwise keep looping
if (TestForBlock(iter)) {
AddToBlock(iter);
// If now that this txs is added we've surpassed our desired priority size
// or have dropped below the AllowFreeThreshold, then we're done adding priority txs
if (nBlockSize >= nBlockPrioritySize || !AllowFree(actualPriority)) {
break;
}
// This tx was successfully added, so
// add transactions that depend on this one to the priority queue to try again
BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter))
{
waitPriIter wpiter = waitPriMap.find(child);
if (wpiter != waitPriMap.end()) {
vecPriority.push_back(TxCoinAgePriority(wpiter->second,child));
std::push_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
waitPriMap.erase(wpiter);
}
}
}
}
fNeedSizeAccounting = fSizeAccounting;
}
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce) void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
{ {
// Update nExtraNonce // Update nExtraNonce

12
src/miner.h

@ -158,10 +158,6 @@ private:
int64_t nLockTimeCutoff; int64_t nLockTimeCutoff;
const CChainParams& chainparams; const CChainParams& chainparams;
// Variables used for addPriorityTxs
int lastFewTxs;
bool blockFinished;
public: public:
BlockAssembler(const CChainParams& chainparams); BlockAssembler(const CChainParams& chainparams);
/** Construct a new block template with coinbase to scriptPubKeyIn */ /** Construct a new block template with coinbase to scriptPubKeyIn */
@ -175,17 +171,9 @@ private:
void AddToBlock(CTxMemPool::txiter iter); void AddToBlock(CTxMemPool::txiter iter);
// Methods for how to add transactions to a block. // Methods for how to add transactions to a block.
/** Add transactions based on tx "priority" */
void addPriorityTxs();
/** Add transactions based on feerate including unconfirmed ancestors */ /** Add transactions based on feerate including unconfirmed ancestors */
void addPackageTxs(); void addPackageTxs();
// helper function for addPriorityTxs
/** Test if tx will still "fit" in the block */
bool TestForBlock(CTxMemPool::txiter iter);
/** Test if tx still has unconfirmed parents not yet in block */
bool isStillDependent(CTxMemPool::txiter iter);
// helper functions for addPackageTxs() // helper functions for addPackageTxs()
/** Remove confirmed (inBlock) entries from given set */ /** Remove confirmed (inBlock) entries from given set */
void onlyUnconfirmed(CTxMemPool::setEntries& testSet); void onlyUnconfirmed(CTxMemPool::setEntries& testSet);

2
src/policy/policy.h

@ -16,8 +16,6 @@ class CCoinsViewCache;
/** Default for -blockmaxsize, which controls the maximum size of block the mining code will create **/ /** Default for -blockmaxsize, which controls the maximum size of block the mining code will create **/
static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000;
/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/
static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0;
/** Default for -blockmaxweight, which controls the range of block weights the mining code will create **/ /** Default for -blockmaxweight, which controls the range of block weights the mining code will create **/
static const unsigned int DEFAULT_BLOCK_MAX_WEIGHT = 3000000; static const unsigned int DEFAULT_BLOCK_MAX_WEIGHT = 3000000;
/** Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by mining code **/ /** Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by mining code **/

1
src/test/miner_tests.cpp

@ -79,7 +79,6 @@ bool TestSequenceLocks(const CTransaction &tx, int flags)
// Test suite for ancestor feerate transaction selection. // Test suite for ancestor feerate transaction selection.
// Implemented as an additional function, rather than a separate test case, // Implemented as an additional function, rather than a separate test case,
// to allow reusing the blockchain created in CreateNewBlock_validity. // to allow reusing the blockchain created in CreateNewBlock_validity.
// Note that this test assumes blockprioritysize is 0.
void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector<CTransactionRef>& txFirst) void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector<CTransactionRef>& txFirst)
{ {
// Test the ancestor feerate transaction selection. // Test the ancestor feerate transaction selection.

13
src/txmempool.h

@ -720,17 +720,4 @@ public:
bool HaveCoins(const uint256 &txid) const; bool HaveCoins(const uint256 &txid) const;
}; };
// We want to sort transactions by coin age priority
typedef std::pair<double, CTxMemPool::txiter> TxCoinAgePriority;
struct TxCoinAgePriorityCompare
{
bool operator()(const TxCoinAgePriority& a, const TxCoinAgePriority& b)
{
if (a.first == b.first)
return CompareTxMemPoolEntryByScore()(*(b.second), *(a.second)); //Reverse order to make sort less than
return a.first < b.first;
}
};
#endif // BITCOIN_TXMEMPOOL_H #endif // BITCOIN_TXMEMPOOL_H

Loading…
Cancel
Save