-
Notifications
You must be signed in to change notification settings - Fork 22
Increased block size up to 4M; txes are allowed to occupy only a subs… #149
Increased block size up to 4M; txes are allowed to occupy only a subs… #149
Conversation
continue; | ||
} | ||
|
||
// Prioritise by fee once past the priority size or we run out of high-priority | ||
// transactions: | ||
if (!fSortedByFee && | ||
((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority))) | ||
((nBlockSize + nTxBaseSize >= nBlockPrioritySize) || !AllowFree(dPriority))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that for the SC support block by default we increased the nBlockPrioritySize
value from 1Mb to 2Mb, so in case we will have the block with Txs only, it will be possible to create a full BlockTxPartition
with free transactions only.
A possible option can be to have different policy for certs and txs in context of priority. For Txs we will allow as before 1 MB of txs partition at most. Considering the fact certs have 2Mb more "space" in the block without Txs, populate block with certs by fee only, but allow zero fee certs as well, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the time being I will set the default priority size value to half the value of the tx partition size, that would comply with the first consideration.
The second part of the comment will be discussed in the final code review.
We also must be careful when we are sorting cetificates based on fee: if we are run out of priority space (or the miner set it to 0) and a certificate has a feeRate < minFeeRate, the certificate would not be included in the block. Therefore we should also add a check when creating a certificate and broadcasting to the network.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After discussion, we don't need to use the maximum priority for certificates because they already have a mechanism to be prioritized over txs up to 2MB. After having reached that limit they will compete by fee with txs. Remove the specific implementation for certs of CCertificateMemPoolEntry::GetPriority and use the standard way for calculating the priority.
Priority block size will be kept at 1MB even if currently is almost useless (the current code base contains a bug because ComputePriority does not check if the tx contains joinsplits then nothing is prioritized if not specifically set by the miner through api).
src/main.cpp
Outdated
if (block.nVersion != BLOCK_VERSION_SC_SUPPORT) | ||
block_size_limit = MAX_BLOCK_SIZE_BEFORE_SC; | ||
|
||
if (block.vtx.empty() || (block.vtx.size() + block.vcert.size()) > block_size_limit || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > block_size_limit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it correct to compare txs + certs number with block size in bytes: (block.vtx.size() + block.vcert.size()) > block_size_limit
? Seems redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We agreed that it might as well be removed, it is comparing different sizes (cardinality vs block size)
src/main.cpp
Outdated
nTxPartSize += tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION); | ||
} | ||
|
||
if (block.nVersion == BLOCK_VERSION_SC_SUPPORT && nTxPartSize > BLOCK_TX_PARTITION_SIZE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may have 2 different loops: first one with nTxPartSize
check only and if there are errors then do another one with CheckTransaction
to prevent complex unnecessary verification:
if (block.nVersion == BLOCK_VERSION_SC_SUPPORT) {
for(const CTransaction& tx: block.vtx) {
nTxPartSize += tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION);
if (nTxPartSize > BLOCK_TX_PARTITION_SIZE)
return error(...);
}
}
for(const CTransaction& tx: block.vtx) {
if (!CheckTransaction(tx, state, verifier)) {
return error("CheckBlock(): CheckTransaction failed");
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, in case of attack the check in this approach is more efficient
After review I didn't find anything wrong. I'll give approval after I had a chance to test this on air gapped testnet later this week. @alsala A couple of questions came up though:
|
Conflicts in qa/rpc-tests/test_framework/mc_test/mc_test.py with #134 This is blocking further testing at the moment. |
|
Linker error on MinGW/Windows build https://travis-ci.com/github/HorizenOfficial/zend_oo/jobs/525496892#L14296-L14320 This is not necessarily caused by this branch, as the CI run was with most open PRs combined into https://github.com/HorizenOfficial/zend_oo/tree/cr/sidechains_integration_step4_test_merge. Edit: Not an issue with this PR but a regression from package crate updates: #152 |
…et (default half) of the block size while this limit does not apply to certs
…on; added a py test
…tor for the case when compressed data are larger than original ones; added UT for bzip2 algo
…for windows (issue #152)
1a483cb
to
387fc54
Compare
@@ -18,6 +18,9 @@ class CAutoFile; | |||
|
|||
inline double AllowFreeThreshold() | |||
{ | |||
// the threshold represents a one day old, 1 ZEN coin (144*4 is the expected number of blocks per day) and a transaction size of 250 bytes. | |||
// TODO, check this: should be: | |||
// return COIN * 144 * 4 / 250; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree
src/init.cpp
Outdated
@@ -510,7 +510,10 @@ std::string HelpMessage(HelpMessageMode mode) | |||
strUsage += HelpMessageGroup(_("Block creation options:")); | |||
strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0)); | |||
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("-blocktxpartitionmaxsize=<n>", strprintf(_("Set maximum partition block size for transcations in bytes (default: %u)"), DEFAULT_BLOCK_TX_PART_MAX_SIZE)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why a user can set it to an arbitrary value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, it is now applicable only in regtest
src/main.cpp
Outdated
if (block.nVersion != BLOCK_VERSION_SC_SUPPORT) | ||
block_size_limit = MAX_BLOCK_SIZE_BEFORE_SC; | ||
|
||
if (block.vtx.empty() || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > block_size_limit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this way we are serializing all txs twice. Is it possible to customize a method to perform both checks for whole block and txs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, added a new CBlock method for getting block size and total tx size
continue; | ||
} | ||
|
||
// Prioritise by fee once past the priority size or we run out of high-priority | ||
// transactions: | ||
if (!fSortedByFee && | ||
((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority))) | ||
((nBlockSize + nTxBaseSize >= nBlockPrioritySize) || !AllowFree(dPriority))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After discussion, we don't need to use the maximum priority for certificates because they already have a mechanism to be prioritized over txs up to 2MB. After having reached that limit they will compete by fee with txs. Remove the specific implementation for certs of CCertificateMemPoolEntry::GetPriority and use the standard way for calculating the priority.
Priority block size will be kept at 1MB even if currently is almost useless (the current code base contains a bug because ComputePriority does not check if the tx contains joinsplits then nothing is prioritized if not specifically set by the miner through api).
src/main.cpp
Outdated
@@ -1303,8 +1303,12 @@ MempoolReturnValue AcceptCertificateToMemoryPool(CTxMemPool& pool, CValidationSt | |||
CCertificateMemPoolEntry entry(cert, nFees, GetTime(), dPriority, chainActive.Height()); | |||
unsigned int nSize = entry.GetCertificateSize(); | |||
|
|||
unsigned int block_priority_size = DEFAULT_BLOCK_PRIORITY_SIZE; | |||
if (!ForkManager::getInstance().areSidechainsSupported(nextBlockHeight)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove it. Useless if
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
…et (default half) of the block size while this limit does not apply to certs