@@ -43,6 +43,7 @@
// its ancestors.
uint64_t nLastBlockTx = 0 ;
+uint64_t nLastBlockSize = 0 ;
uint64_t nLastBlockWeight = 0 ;
int64_t UpdateTime (CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
@@ -63,13 +64,18 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
BlockAssembler::Options::Options () {
blockMinFeeRate = CFeeRate (DEFAULT_BLOCK_MIN_TX_FEE);
nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;
+ nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;
}
BlockAssembler::BlockAssembler (const CChainParams& params, const Options& options) : chainparams(params)
{
blockMinFeeRate = options.blockMinFeeRate ;
// Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity:
nBlockMaxWeight = std::max<size_t >(4000 , std::min<size_t >(MAX_BLOCK_WEIGHT - 4000 , options.nBlockMaxWeight ));
+ // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity:
+ nBlockMaxSize = std::max<size_t >(1000 , std::min<size_t >(MAX_BLOCK_SERIALIZED_SIZE - 1000 , options.nBlockMaxSize ));
+ // Whether we need to account for byte usage (in addition to weight usage)
+ fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE - 1000 );
}
static BlockAssembler::Options DefaultOptions (const CChainParams& params)
@@ -79,7 +85,20 @@ static BlockAssembler::Options DefaultOptions(const CChainParams& params)
// If only one is given, only restrict the specified resource.
// If both are given, restrict both.
BlockAssembler::Options options;
- options.nBlockMaxWeight = gArgs .GetArg (" -blockmaxweight" , DEFAULT_BLOCK_MAX_WEIGHT);
+ options.nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;
+ options.nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;
+ bool fWeightSet = false ;
+ if (gArgs .IsArgSet (" -blockmaxweight" )) {
+ options.nBlockMaxWeight = gArgs .GetArg (" -blockmaxweight" , DEFAULT_BLOCK_MAX_WEIGHT);
+ options.nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE;
+ fWeightSet = true ;
+ }
+ if (gArgs .IsArgSet (" -blockmaxsize" )) {
+ options.nBlockMaxSize = gArgs .GetArg (" -blockmaxsize" , DEFAULT_BLOCK_MAX_SIZE);
+ if (!fWeightSet ) {
+ options.nBlockMaxWeight = options.nBlockMaxSize * WITNESS_SCALE_FACTOR;
+ }
+ }
if (gArgs .IsArgSet (" -blockmintxfee" )) {
CAmount n = 0 ;
ParseMoney (gArgs .GetArg (" -blockmintxfee" , " " ), n);
@@ -97,6 +116,7 @@ void BlockAssembler::resetBlock()
inBlock.clear ();
// Reserve space for coinbase tx
+ nBlockSize = 1000 ;
nBlockWeight = 4000 ;
nBlockSigOpsCost = 400 ;
fIncludeWitness = false ;
@@ -155,6 +175,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
int64_t nTime1 = GetTimeMicros ();
nLastBlockTx = nBlockTx;
+ nLastBlockSize = nBlockSize;
nLastBlockWeight = nBlockWeight;
// Create coinbase transaction.
@@ -169,7 +190,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment (*pblock, pindexPrev, chainparams.GetConsensus ());
pblocktemplate->vTxFees[0 ] = -nFees;
- LogPrintf (" CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n " , GetBlockWeight (*pblock), nBlockTx, nFees, nBlockSigOpsCost);
+ uint64_t nSerializeSize = GetSerializeSize (*pblock, SER_NETWORK, PROTOCOL_VERSION);
+ LogPrintf (" CreateNewBlock(): total size: %u block weight: %u txs: %u fees: %ld sigops %d\n " , nSerializeSize, GetBlockWeight (*pblock), nBlockTx, nFees, nBlockSigOpsCost);
// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash ();
@@ -216,13 +238,22 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost
// - 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
for (const CTxMemPool::txiter it : package) {
if (!IsFinalTx (it->GetTx (), nHeight, nLockTimeCutoff))
return false ;
if (!fIncludeWitness && it->GetTx ().HasWitness ())
return false ;
+ if (fNeedSizeAccounting ) {
+ uint64_t nTxSize = ::GetSerializeSize (it->GetTx (), SER_NETWORK, PROTOCOL_VERSION);
+ if (nPotentialBlockSize + nTxSize >= nBlockMaxSize) {
+ return false ;
+ }
+ nPotentialBlockSize += nTxSize;
+ }
}
return true ;
}
@@ -232,6 +263,9 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
pblock->vtx.emplace_back (iter->GetSharedTx ());
pblocktemplate->vTxFees.push_back (iter->GetFee ());
pblocktemplate->vTxSigOpsCost.push_back (iter->GetSigOpCost ());
+ if (fNeedSizeAccounting ) {
+ nBlockSize += ::GetSerializeSize (iter->GetTx (), SER_NETWORK, PROTOCOL_VERSION);
+ }
nBlockWeight += iter->GetTxWeight ();
++nBlockTx;
nBlockSigOpsCost += iter->GetSigOpCost ();
0 comments on commit
c5047d0