aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-07-18 08:23:38 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2016-07-18 08:23:45 +0200
commitf5660d381a37383a07610262d12ec6f8ce47cf01 (patch)
treed9160fcfa8df54d4a02ce7710cb900e52b730805
parent238300b39894ef3a79540687d127a928d7b3c53c (diff)
parentc1d61fbd080bcc29589b8d467df98efb7e89d231 (diff)
Merge #8295: Mining-related fixups for 0.13.0
c1d61fb Add warning if -blockminsize is used. (Suhas Daftuar) 27362dd Remove -blockminsize option (Suhas Daftuar) d2e46e1 Remove addScoreTxs() (Suhas Daftuar) 6dd4bc2 Exclude witness transactions in addPackageTxs() pre-segwit activation (Suhas Daftuar) f15c2cd CreateNewBlock: add support for size-accounting to addPackageTxs (Suhas Daftuar)
-rwxr-xr-xcontrib/devtools/check-doc.py2
-rw-r--r--src/init.cpp4
-rw-r--r--src/miner.cpp101
-rw-r--r--src/miner.h15
-rw-r--r--src/policy/policy.h3
5 files changed, 36 insertions, 89 deletions
diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py
index 06c9551ceb..9ea0131ac3 100755
--- a/contrib/devtools/check-doc.py
+++ b/contrib/devtools/check-doc.py
@@ -21,7 +21,7 @@ CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' %s" % (CMD_RO
REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"')
REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")')
# list unsupported, deprecated and duplicate args as they need no documentation
-SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-prematurewitness', '-walletprematurewitness', '-promiscuousmempoolflags'])
+SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-prematurewitness', '-walletprematurewitness', '-promiscuousmempoolflags', '-blockminsize'])
def main():
used = check_output(CMD_GREP_ARGS, shell=True)
diff --git a/src/init.cpp b/src/init.cpp
index 7e91e0ba8b..d127ecd48f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -453,7 +453,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageGroup(_("Block creation options:"));
strUsage += HelpMessageOpt("-blockmaxcost=<n>", strprintf(_("Set maximum block cost (default: %d)"), DEFAULT_BLOCK_MAX_COST));
- 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 (showDebug)
@@ -877,6 +876,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (GetBoolArg("-whitelistalwaysrelay", false))
InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay."));
+ if (mapArgs.count("-blockminsize"))
+ InitWarning("Unsupported argument -blockminsize ignored.");
+
// Checkmempool and checkblockindex default to true in regtest mode
int ratio = std::min<int>(std::max<int>(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
if (ratio != 0) {
diff --git a/src/miner.cpp b/src/miner.cpp
index cfc2dae56e..8153fb9f9e 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -94,18 +94,14 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams)
nBlockMaxCost = nBlockMaxSize * WITNESS_SCALE_FACTOR;
}
}
+
// Limit cost to between 4K and MAX_BLOCK_COST-4K for sanity:
nBlockMaxCost = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_COST-4000), nBlockMaxCost));
// Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity:
nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SERIALIZED_SIZE-1000), nBlockMaxSize));
- // Minimum block size you want to create; block will be filled with free transactions
- // until there are no more or the block reaches this size:
- nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE);
- nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
-
// Whether we need to account for byte usage (in addition to cost usage)
- fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000) || (nBlockMinSize > 0);
+ fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000);
}
void BlockAssembler::resetBlock()
@@ -167,13 +163,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
addPriorityTxs();
- if (fNeedSizeAccounting) {
- // addPackageTxs (the CPFP-based algorithm) cannot deal with size based
- // accounting, so fall back to the old algorithm.
- addScoreTxs();
- } else {
- addPackageTxs();
- }
+ addPackageTxs();
nLastBlockTx = nBlockTx;
nLastBlockSize = nBlockSize;
@@ -241,13 +231,26 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost
return true;
}
-// Block size and sigops have already been tested. Check that all transactions
-// are final.
-bool BlockAssembler::TestPackageFinality(const CTxMemPool::setEntries& package)
+// Perform transaction-level checks before adding to block:
+// - transaction finality (locktime)
+// - premature witness (in case segwit transactions are added to mempool before
+// segwit activation)
+// - serialized size (in case -blockmaxsize is in use)
+bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& package)
{
+ uint64_t nPotentialBlockSize = nBlockSize; // only used with fNeedSizeAccounting
BOOST_FOREACH (const CTxMemPool::txiter it, package) {
if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff))
return false;
+ if (!fIncludeWitness && !it->GetTx().wit.IsNull())
+ return false;
+ if (fNeedSizeAccounting) {
+ uint64_t nTxSize = ::GetSerializeSize(it->GetTx(), SER_NETWORK, PROTOCOL_VERSION);
+ if (nPotentialBlockSize + nTxSize >= nBlockMaxSize) {
+ return false;
+ }
+ nPotentialBlockSize += nTxSize;
+ }
}
return true;
}
@@ -330,66 +333,6 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
}
}
-void BlockAssembler::addScoreTxs()
-{
- std::priority_queue<CTxMemPool::txiter, std::vector<CTxMemPool::txiter>, ScoreCompare> clearedTxs;
- CTxMemPool::setEntries waitSet;
- CTxMemPool::indexed_transaction_set::index<mining_score>::type::iterator mi = mempool.mapTx.get<mining_score>().begin();
- CTxMemPool::txiter iter;
- while (!blockFinished && (mi != mempool.mapTx.get<mining_score>().end() || !clearedTxs.empty()))
- {
- // If no txs that were previously postponed are available to try
- // again, then try the next highest score tx
- if (clearedTxs.empty()) {
- iter = mempool.mapTx.project<0>(mi);
- mi++;
- }
- // If a previously postponed tx is available to try again, then it
- // has higher score than all untried so far txs
- else {
- iter = clearedTxs.top();
- clearedTxs.pop();
- }
-
- // If tx already in block, skip (added by addPriorityTxs)
- if (inBlock.count(iter)) {
- continue;
- }
-
- // cannot accept witness transactions into a non-witness block
- if (!fIncludeWitness && !iter->GetTx().wit.IsNull())
- continue;
-
- // If tx is dependent on other mempool txs which haven't yet been included
- // then put it in the waitSet
- if (isStillDependent(iter)) {
- waitSet.insert(iter);
- continue;
- }
-
- // If the fee rate is below the min fee rate for mining, then we're done
- // adding txs based on score (fee rate)
- if (iter->GetModifiedFee() < ::minRelayTxFee.GetFee(iter->GetTxSize()) && nBlockSize >= nBlockMinSize) {
- return;
- }
-
- // If this tx fits in the block add it, otherwise keep looping
- if (TestForBlock(iter)) {
- AddToBlock(iter);
-
- // 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))
- {
- if (waitSet.count(child)) {
- clearedTxs.push(child);
- waitSet.erase(child);
- }
- }
- }
- }
-}
-
void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded,
indexed_modified_transaction_set &mapModifiedTx)
{
@@ -539,7 +482,7 @@ void BlockAssembler::addPackageTxs()
ancestors.insert(iter);
// Test if all tx's are Final
- if (!TestPackageFinality(ancestors)) {
+ if (!TestPackageTransactions(ancestors)) {
if (fUsingModified) {
mapModifiedTx.get<ancestor_score>().erase(modit);
failedTx.insert(iter);
@@ -573,6 +516,7 @@ void BlockAssembler::addPriorityTxs()
return;
}
+ bool fSizeAccounting = fNeedSizeAccounting;
fNeedSizeAccounting = true;
// This vector will be sorted into a priority queue:
@@ -624,7 +568,7 @@ void BlockAssembler::addPriorityTxs()
// 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;
+ break;
}
// This tx was successfully added, so
@@ -640,6 +584,7 @@ void BlockAssembler::addPriorityTxs()
}
}
}
+ fNeedSizeAccounting = fSizeAccounting;
}
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
diff --git a/src/miner.h b/src/miner.h
index b303a8fa3c..d16e37bb59 100644
--- a/src/miner.h
+++ b/src/miner.h
@@ -141,7 +141,7 @@ private:
// Configuration parameters for the block size
bool fIncludeWitness;
- unsigned int nBlockMaxCost, nBlockMaxSize, nBlockMinSize;
+ unsigned int nBlockMaxCost, nBlockMaxSize;
bool fNeedSizeAccounting;
// Information on the current status of the block
@@ -157,7 +157,7 @@ private:
int64_t nLockTimeCutoff;
const CChainParams& chainparams;
- // Variables used for addScoreTxs and addPriorityTxs
+ // Variables used for addPriorityTxs
int lastFewTxs;
bool blockFinished;
@@ -174,14 +174,12 @@ private:
void AddToBlock(CTxMemPool::txiter iter);
// 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();
/** Add transactions based on feerate including unconfirmed ancestors */
void addPackageTxs();
- // helper function for addScoreTxs and addPriorityTxs
+ // 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 */
@@ -192,8 +190,11 @@ private:
void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
/** Test if a new package would "fit" in the block */
bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost);
- /** Test if a set of transactions are all final */
- bool TestPackageFinality(const CTxMemPool::setEntries& package);
+ /** Perform checks on each transaction in a package:
+ * locktime, premature-witness, serialized size (if necessary)
+ * These checks should always succeed, and they're here
+ * only as an extra check in case of suboptimal node configuration */
+ bool TestPackageTransactions(const CTxMemPool::setEntries& package);
/** Return true if given transaction from mapTx has already been evaluated,
* or if the transaction's cached data in mapTx is incorrect. */
bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx);
diff --git a/src/policy/policy.h b/src/policy/policy.h
index fefb562ff9..29a8cc57c2 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -14,9 +14,8 @@
class CCoinsViewCache;
-/** Default for -blockmaxsize and -blockminsize, which control the range of sizes 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_MIN_SIZE = 0;
/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/
static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0;
/** Default for -blockmaxcost, which control the range of block costs the mining code will create **/