mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-02-01 01:34:42 +00:00
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)
This commit is contained in:
commit
f5660d381a
@ -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_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"')
|
||||||
REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")')
|
REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")')
|
||||||
# list unsupported, deprecated and duplicate args as they need no documentation
|
# 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():
|
def main():
|
||||||
used = check_output(CMD_GREP_ARGS, shell=True)
|
used = check_output(CMD_GREP_ARGS, shell=True)
|
||||||
|
@ -453,7 +453,6 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||||||
|
|
||||||
strUsage += HelpMessageGroup(_("Block creation options:"));
|
strUsage += HelpMessageGroup(_("Block creation options:"));
|
||||||
strUsage += HelpMessageOpt("-blockmaxcost=<n>", strprintf(_("Set maximum block cost (default: %d)"), DEFAULT_BLOCK_MAX_COST));
|
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("-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("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
|
||||||
if (showDebug)
|
if (showDebug)
|
||||||
@ -877,6 +876,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
if (GetBoolArg("-whitelistalwaysrelay", false))
|
if (GetBoolArg("-whitelistalwaysrelay", false))
|
||||||
InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay."));
|
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
|
// 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);
|
int ratio = std::min<int>(std::max<int>(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
|
||||||
if (ratio != 0) {
|
if (ratio != 0) {
|
||||||
|
101
src/miner.cpp
101
src/miner.cpp
@ -94,18 +94,14 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams)
|
|||||||
nBlockMaxCost = nBlockMaxSize * WITNESS_SCALE_FACTOR;
|
nBlockMaxCost = nBlockMaxSize * WITNESS_SCALE_FACTOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit cost to between 4K and MAX_BLOCK_COST-4K for sanity:
|
// 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));
|
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:
|
// 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));
|
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)
|
// 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()
|
void BlockAssembler::resetBlock()
|
||||||
@ -167,13 +163,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
|
|||||||
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
|
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
|
||||||
|
|
||||||
addPriorityTxs();
|
addPriorityTxs();
|
||||||
if (fNeedSizeAccounting) {
|
addPackageTxs();
|
||||||
// addPackageTxs (the CPFP-based algorithm) cannot deal with size based
|
|
||||||
// accounting, so fall back to the old algorithm.
|
|
||||||
addScoreTxs();
|
|
||||||
} else {
|
|
||||||
addPackageTxs();
|
|
||||||
}
|
|
||||||
|
|
||||||
nLastBlockTx = nBlockTx;
|
nLastBlockTx = nBlockTx;
|
||||||
nLastBlockSize = nBlockSize;
|
nLastBlockSize = nBlockSize;
|
||||||
@ -241,13 +231,26 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block size and sigops have already been tested. Check that all transactions
|
// Perform transaction-level checks before adding to block:
|
||||||
// are final.
|
// - transaction finality (locktime)
|
||||||
bool BlockAssembler::TestPackageFinality(const CTxMemPool::setEntries& package)
|
// - 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) {
|
BOOST_FOREACH (const CTxMemPool::txiter it, package) {
|
||||||
if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff))
|
if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff))
|
||||||
return false;
|
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;
|
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,
|
void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded,
|
||||||
indexed_modified_transaction_set &mapModifiedTx)
|
indexed_modified_transaction_set &mapModifiedTx)
|
||||||
{
|
{
|
||||||
@ -539,7 +482,7 @@ void BlockAssembler::addPackageTxs()
|
|||||||
ancestors.insert(iter);
|
ancestors.insert(iter);
|
||||||
|
|
||||||
// Test if all tx's are Final
|
// Test if all tx's are Final
|
||||||
if (!TestPackageFinality(ancestors)) {
|
if (!TestPackageTransactions(ancestors)) {
|
||||||
if (fUsingModified) {
|
if (fUsingModified) {
|
||||||
mapModifiedTx.get<ancestor_score>().erase(modit);
|
mapModifiedTx.get<ancestor_score>().erase(modit);
|
||||||
failedTx.insert(iter);
|
failedTx.insert(iter);
|
||||||
@ -573,6 +516,7 @@ void BlockAssembler::addPriorityTxs()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fSizeAccounting = fNeedSizeAccounting;
|
||||||
fNeedSizeAccounting = true;
|
fNeedSizeAccounting = true;
|
||||||
|
|
||||||
// This vector will be sorted into a priority queue:
|
// 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
|
// 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
|
// or have dropped below the AllowFreeThreshold, then we're done adding priority txs
|
||||||
if (nBlockSize >= nBlockPrioritySize || !AllowFree(actualPriority)) {
|
if (nBlockSize >= nBlockPrioritySize || !AllowFree(actualPriority)) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This tx was successfully added, so
|
// 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)
|
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
|
||||||
|
15
src/miner.h
15
src/miner.h
@ -141,7 +141,7 @@ private:
|
|||||||
|
|
||||||
// Configuration parameters for the block size
|
// Configuration parameters for the block size
|
||||||
bool fIncludeWitness;
|
bool fIncludeWitness;
|
||||||
unsigned int nBlockMaxCost, nBlockMaxSize, nBlockMinSize;
|
unsigned int nBlockMaxCost, nBlockMaxSize;
|
||||||
bool fNeedSizeAccounting;
|
bool fNeedSizeAccounting;
|
||||||
|
|
||||||
// Information on the current status of the block
|
// Information on the current status of the block
|
||||||
@ -157,7 +157,7 @@ private:
|
|||||||
int64_t nLockTimeCutoff;
|
int64_t nLockTimeCutoff;
|
||||||
const CChainParams& chainparams;
|
const CChainParams& chainparams;
|
||||||
|
|
||||||
// Variables used for addScoreTxs and addPriorityTxs
|
// Variables used for addPriorityTxs
|
||||||
int lastFewTxs;
|
int lastFewTxs;
|
||||||
bool blockFinished;
|
bool blockFinished;
|
||||||
|
|
||||||
@ -174,14 +174,12 @@ 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 modified feerate */
|
|
||||||
void addScoreTxs();
|
|
||||||
/** Add transactions based on tx "priority" */
|
/** Add transactions based on tx "priority" */
|
||||||
void addPriorityTxs();
|
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 addScoreTxs and addPriorityTxs
|
// helper function for addPriorityTxs
|
||||||
/** Test if tx will still "fit" in the block */
|
/** Test if tx will still "fit" in the block */
|
||||||
bool TestForBlock(CTxMemPool::txiter iter);
|
bool TestForBlock(CTxMemPool::txiter iter);
|
||||||
/** Test if tx still has unconfirmed parents not yet in block */
|
/** Test if tx still has unconfirmed parents not yet in block */
|
||||||
@ -192,8 +190,11 @@ private:
|
|||||||
void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
|
void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
|
||||||
/** Test if a new package would "fit" in the block */
|
/** Test if a new package would "fit" in the block */
|
||||||
bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost);
|
bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost);
|
||||||
/** Test if a set of transactions are all final */
|
/** Perform checks on each transaction in a package:
|
||||||
bool TestPackageFinality(const CTxMemPool::setEntries& 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,
|
/** Return true if given transaction from mapTx has already been evaluated,
|
||||||
* or if the transaction's cached data in mapTx is incorrect. */
|
* or if the transaction's cached data in mapTx is incorrect. */
|
||||||
bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx);
|
bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx);
|
||||||
|
@ -14,9 +14,8 @@
|
|||||||
|
|
||||||
class CCoinsViewCache;
|
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_MAX_SIZE = 750000;
|
||||||
static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0;
|
|
||||||
/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/
|
/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/
|
||||||
static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0;
|
static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0;
|
||||||
/** Default for -blockmaxcost, which control the range of block costs the mining code will create **/
|
/** Default for -blockmaxcost, which control the range of block costs the mining code will create **/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user