[mining] Remove -blockprioritysize.
Remove ability of mining code to fill part of a block with transactions sorted by coin age. (cherry picked from commit bitcoin/bitcoin@272b25a6a9) Zcash: * Add release notes. * Remove a static assertion that no longer applies. * Spell "prioritise" and "prioritisation" (when referring to tx prioritisation) consistently with 'ise', to match the "prioritisetransaction" RPC call. Signed-off-by: Daira Emma Hopwood <daira@jacaranda.org>
This commit is contained in:
parent
9231eed603
commit
dbf52938af
|
@ -39,6 +39,14 @@ Changes to Transaction Fee Selection
|
|||
`sendmany`, and `fundrawtransaction`) to use a zero fee for "small" transactions
|
||||
that spend "old" inputs. It will now cause a warning on node startup if used.
|
||||
|
||||
Changes to Block Template Construction
|
||||
--------------------------------------
|
||||
|
||||
- The block template construction algorithm no longer favours transactions that
|
||||
were previously considered "high priority" because they spent older inputs. The
|
||||
`-blockprioritysize` config option, which configured the portion of the block
|
||||
reserved for these transactions, has been removed and is now ignored.
|
||||
|
||||
Removal of Priority Estimation
|
||||
------------------------------
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
|
|||
self.nodes = []
|
||||
# Start nodes with tiny block size of 11kb
|
||||
args = [
|
||||
"-blockprioritysize=7000",
|
||||
"-blockmaxsize=11000",
|
||||
"-maxorphantx=1000",
|
||||
"-relaypriority=true",
|
||||
|
@ -42,8 +41,6 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
|
|||
self.sync_all()
|
||||
|
||||
def run_test (self):
|
||||
# tx priority is calculated: priority = sum(input_value_in_base_units * input_age)/size_in_bytes
|
||||
|
||||
print("Mining 11kb blocks...")
|
||||
self.nodes[0].generate(501)
|
||||
|
||||
|
@ -60,8 +57,8 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
|
|||
# could take up to 128s. So use a higher timeout on the mempool sync.
|
||||
sync_mempools(self.nodes, timeout=200)
|
||||
|
||||
# Create tx of lower value to be prioritized on node 0
|
||||
# Older transactions get mined first, so this lower value, newer tx is unlikely to be mined without prioritisation
|
||||
# Create tx to be prioritised on node 0
|
||||
# This tx will not be mined without prioritisation.
|
||||
priority_tx_0 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
|
||||
|
||||
# Check that priority_tx_0 is not in block_template() prior to prioritisation
|
||||
|
@ -76,7 +73,7 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
|
|||
priority_success = self.nodes[0].prioritisetransaction(priority_tx_0, 1000, int(3 * base_fee * COIN))
|
||||
assert(priority_success)
|
||||
|
||||
# Check that prioritized transaction is not in getblocktemplate()
|
||||
# Check that prioritised transaction is not in getblocktemplate()
|
||||
# (not updated because no new txns)
|
||||
in_block_template = False
|
||||
block_template = self.nodes[0].getblocktemplate()
|
||||
|
@ -89,7 +86,7 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
|
|||
# Sending a new transaction will make getblocktemplate refresh within 10s
|
||||
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
|
||||
|
||||
# Check that prioritized transaction is not in getblocktemplate()
|
||||
# Check that prioritised transaction is not in getblocktemplate()
|
||||
# (too soon)
|
||||
in_block_template = False
|
||||
block_template = self.nodes[0].getblocktemplate()
|
||||
|
@ -99,7 +96,7 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
|
|||
break
|
||||
assert_equal(in_block_template, False)
|
||||
|
||||
# Check that prioritized transaction is in getblocktemplate()
|
||||
# Check that prioritised transaction is in getblocktemplate()
|
||||
# getblocktemplate() will refresh after 1 min, or after 10 sec if new transaction is added to mempool
|
||||
# Mempool is probed every 10 seconds. We'll give getblocktemplate() a maximum of 30 seconds to refresh
|
||||
block_template = self.nodes[0].getblocktemplate()
|
||||
|
@ -117,7 +114,7 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
|
|||
|
||||
assert(in_block_template)
|
||||
|
||||
# Node 1 doesn't get the next block, so this *shouldn't* be mined despite being prioritized on node 1
|
||||
# Node 1 doesn't get the next block, so this *shouldn't* be mined despite being prioritised on node 1
|
||||
priority_tx_1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 0.1)
|
||||
self.nodes[1].prioritisetransaction(priority_tx_1, 1000, int(3 * base_fee * COIN))
|
||||
|
||||
|
|
|
@ -408,10 +408,6 @@ Block creation options:
|
|||
-blockmaxsize=<n>
|
||||
Set maximum block size in bytes (default: 2000000)
|
||||
|
||||
-blockprioritysize=<n>
|
||||
Set maximum size of high-priority/low-fee transactions in bytes
|
||||
(default: 1000000)
|
||||
|
||||
Mining options:
|
||||
|
||||
-gen
|
||||
|
|
|
@ -193,13 +193,12 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
|
||||
# (17k is room enough for 110 or so transactions)
|
||||
self.nodes.append(start_node(1, self.options.tmpdir,
|
||||
["-blockprioritysize=1500", "-blockmaxsize=18000",
|
||||
"-maxorphantx=1000", "-relaypriority=0", "-debug=estimatefee"]))
|
||||
["-blockmaxsize=18000", "-maxorphantx=1000", "-relaypriority=0", "-debug=estimatefee"]))
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
|
||||
# Node2 is a stingy miner, that
|
||||
# produces too small blocks (room for only 70 or so transactions)
|
||||
node2args = ["-blockprioritysize=0", "-blockmaxsize=12000", "-maxorphantx=1000", "-relaypriority=0"]
|
||||
node2args = ["-blockmaxsize=12000", "-maxorphantx=1000", "-relaypriority=0"]
|
||||
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, node2args))
|
||||
connect_nodes(self.nodes[0], 2)
|
||||
|
|
|
@ -504,7 +504,6 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageGroup(_("Block creation options:"));
|
||||
strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_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));
|
||||
if (GetBoolArg("-help-debug", false))
|
||||
strUsage += HelpMessageOpt("-blockversion=<n>", strprintf("Override block version to test forking scenarios (default: %d)", (int)CBlock::CURRENT_VERSION));
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ using namespace std;
|
|||
//
|
||||
// Unconfirmed transactions in the memory pool often depend on other
|
||||
// transactions in the memory pool. When we select transactions from the
|
||||
// pool, we select by highest priority or fee rate, so we might consider
|
||||
// transactions that depend on transactions that aren't yet in the block.
|
||||
// pool, we select by highest fee rate, so we might consider transactions
|
||||
// that depend on transactions that aren't yet in the block.
|
||||
|
||||
std::optional<uint64_t> last_block_num_txs;
|
||||
std::optional<uint64_t> last_block_size;
|
||||
|
@ -437,7 +437,6 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(
|
|||
}
|
||||
}
|
||||
|
||||
addPriorityTxs();
|
||||
addScoreTxs();
|
||||
|
||||
last_block_num_txs = nBlockTx;
|
||||
|
@ -704,80 +703,6 @@ void BlockAssembler::addScoreTxs()
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// This vector will be sorted into a priority queue:
|
||||
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;
|
||||
}
|
||||
|
||||
// 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)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This tx was successfully added, so
|
||||
// add transactions that depend on this one to the priority queue to try again
|
||||
for (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Internal miner
|
||||
|
|
|
@ -148,8 +148,6 @@ private:
|
|||
// Methods for how to add transactions to a block.
|
||||
/** Add transactions based on modified feerate */
|
||||
void addScoreTxs();
|
||||
/** Add transactions based on tx "priority" */
|
||||
void addPriorityTxs();
|
||||
|
||||
// helper function for addScoreTxs and addPriorityTxs
|
||||
/** Test if tx will still "fit" in the block */
|
||||
|
|
|
@ -18,8 +18,7 @@ class CCoinsViewCache;
|
|||
/** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/
|
||||
static const unsigned int DEFAULT_BLOCK_MAX_SIZE = MAX_BLOCK_SIZE;
|
||||
static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0;
|
||||
/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/
|
||||
static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = DEFAULT_BLOCK_MAX_SIZE / 2;
|
||||
|
||||
/** Maximum number of signature check operations in an IsStandard() P2SH script */
|
||||
static const unsigned int MAX_P2SH_SIGOPS = 15;
|
||||
/** The maximum number of sigops we're willing to relay/mine in a single tx */
|
||||
|
@ -44,7 +43,6 @@ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_
|
|||
|
||||
// Sanity check the magic numbers when we change them
|
||||
static_assert(DEFAULT_BLOCK_MAX_SIZE <= MAX_BLOCK_SIZE);
|
||||
static_assert(DEFAULT_BLOCK_PRIORITY_SIZE <= DEFAULT_BLOCK_MAX_SIZE);
|
||||
|
||||
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType);
|
||||
/**
|
||||
|
|
|
@ -388,7 +388,7 @@ public:
|
|||
boost::multi_index::identity<CTxMemPoolEntry>,
|
||||
CompareTxMemPoolEntryByDescendantScore
|
||||
>,
|
||||
// sorted by score (for mining prioritization)
|
||||
// sorted by score (for mining prioritisation)
|
||||
boost::multi_index::ordered_unique<
|
||||
boost::multi_index::tag<mining_score>,
|
||||
boost::multi_index::identity<CTxMemPoolEntry>,
|
||||
|
@ -673,17 +673,4 @@ public:
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue