Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Increased block size up to 4M; txes are allowed to occupy only a subs… #149

Merged
merged 14 commits into from
Sep 2, 2021

Conversation

alsala
Copy link
Contributor

@alsala alsala commented Jul 7, 2021

…et (default half) of the block size while this limit does not apply to certs

@alsala alsala requested review from i-Alex and ptagl July 7, 2021 13:03
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)))
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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)
Copy link
Contributor

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.

Copy link
Contributor Author

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)
Copy link
Contributor

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");
  }
}

Copy link
Contributor Author

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

@alsala alsala requested a review from cronicc July 16, 2021 14:16
@cronicc
Copy link
Member

cronicc commented Jul 19, 2021

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.
I'll also create a separate branch with all PRs including this merged for a CI run.

@alsala A couple of questions came up though:

  1. Do we need to adjust block heights in any RPC tests so that they run after SC fork activation (thus making sure they still pass with the new rules), or has this already been done?
  2. Do we need to adjust any existing tests to incorporate cert tx? Tests that are related to filtering on the block(template), mempool or RPC level come to mind, e.g. getblocktemplate_priority.py, mempool_tx_input_limit.py, listtransactions.py, prioritisetransaction.py.
  3. Related to 2, do -mempooltxinputlimit and -blockmaxcomplexity apply to certificates and should they?

@cronicc
Copy link
Member

cronicc commented Jul 19, 2021

Conflicts in qa/rpc-tests/test_framework/mc_test/mc_test.py with #134

This is blocking further testing at the moment.

@alsala
Copy link
Contributor Author

alsala commented Jul 19, 2021

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.
I'll also create a separate branch with all PRs including this merged for a CI run.

@alsala A couple of questions came up though:

1. Do we need to adjust block heights in any RPC tests so that they run after SC fork activation (thus making sure they still pass with the new rules), or has this already been done?

2. Do we need to adjust any existing tests to incorporate cert tx? Tests that are related to filtering on the block(template), mempool or RPC level come to mind, e.g. [getblocktemplate_priority.py](https://github.com/HorizenOfficial/zend_oo/blob/as/increase_block_size/qa/rpc-tests/getblocktemplate_priority.py), [mempool_tx_input_limit.py](https://github.com/HorizenOfficial/zend_oo/blob/as/increase_block_size/qa/rpc-tests/mempool_tx_input_limit.py), [listtransactions.py](https://github.com/HorizenOfficial/zend_oo/blob/as/increase_block_size/qa/rpc-tests/listtransactions.py), [prioritisetransaction.py](https://github.com/HorizenOfficial/zend_oo/blob/as/increase_block_size/qa/rpc-tests/prioritisetransaction.py).

3. Related to 2, do `-mempooltxinputlimit` and `-blockmaxcomplexity` apply to certificates and should they?
  • I would suggest to open a couple of separate issues for (1) and (2) above. For instance in (1) we could increase the size of the node cache blockchain enlarging it from 200 to 420, which in regtest is the height of the SC fork, and probably some test would be modified accordingly.
  • As far as (3) is concerned, yes both those parameters are handled for txes and certificates.

@cronicc
Copy link
Member

cronicc commented Jul 19, 2021

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

@cronicc cronicc linked an issue Jul 21, 2021 that may be closed by this pull request
@@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

qa/rpc-tests/sc_cert_bwt_amount_rounding.py Show resolved Hide resolved
qa/rpc-tests/sc_block_partitions.py Outdated Show resolved Hide resolved
qa/rpc-tests/sc_block_partitions.py Outdated Show resolved Hide resolved
qa/rpc-tests/sc_block_partitions.py Outdated Show resolved Hide resolved
qa/rpc-tests/sc_block_partitions.py Outdated Show resolved Hide resolved
qa/rpc-tests/sc_block_partitions.py Outdated Show resolved Hide resolved
qa/rpc-tests/sc_cert_bwt_amount_rounding.py Outdated Show resolved Hide resolved
qa/rpc-tests/sc_cert_bwt_amount_rounding.py Outdated Show resolved Hide resolved
qa/rpc-tests/sc_cert_bwt_amount_rounding.py Outdated Show resolved Hide resolved
qa/rpc-tests/sc_cert_bwt_amount_rounding.py Outdated Show resolved Hide resolved
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));
Copy link
Contributor

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?

Copy link
Contributor Author

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 Show resolved Hide resolved
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)
Copy link
Contributor

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?

Copy link
Contributor Author

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

src/main.cpp Outdated Show resolved Hide resolved
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)))
Copy link
Contributor Author

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))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove it. Useless if

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@Cermelli Cermelli merged commit e5dbbd2 into sidechains_integration_code_review Sep 2, 2021
alsala added a commit that referenced this pull request Sep 8, 2021
@alsala alsala mentioned this pull request Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Regression in Windows MinGW build
6 participants