In the past, the account name "blocktwitter" made continuous transactions on the EOS network, causing Dapps on EOS not to function properly. Due to Blocktwitter, the CPU limit of the EOS network declined rapidly. Additionally, EOS Knights and EOS dice users had trouble using them.
So we wanted to find out the reason for this occurrence and a solution for the "CPU limit" problem.
First, let's find out how the EOSIO software calculates a CPU Max Limit for specific accounts. Afterwards, we will explain the solution to the blocktwitter case.
You may have tried using block explorers to see how much CPU/NET resources you have. However, as you can see, the maximum CPU volume continuous to change whenever you refresh the explorer even though you haven't changed the staking amounts.
Why is this happening?!
We couldn't find a proper explanation, so we decided to look at the code ourselves to see what the heck is happening.
Here is EOSIO's algorithm for estimating the CPU Max Limit.
1. window_size = 24x60x60x1000/500 (fixed value)
- that is 2x24x60x60
2. virtual_capacity _in_window
= virtual_cpu_limit x window_size
= virtual_cpu_limit x 2x24x60x60
3. user_weight = amount of EOS that user staked for CPU
4. all_user_weight = amount of EOS that every user staked for CPU
CPU의 Max Limit = (virtual_cpu_capacity_in_window x user_weight) / all_user_weight = virtual_cpu_limit x 2x24x60x60 x user_weight / all_user_weight = virtual_cpu_limit x 172800 x (rato of "how much I staked for CPU" / "how much every user staked for CPU")
Therefore, if both the total staking amount and your staking amount do not change, then "virtual_cpu_limit" is the reason for why the CPU Max Limit varies.
You can check current virtual_block_cpu_limit here :
if you refresh it, you can see the value changes
Now we know the reason for why the maximum CPU limit continues to change. It's because of "virtual_cpu_limit"
The "virtual_cpu_limit" is calculated when each block is produced. Here is an explanation of the algorithm :
Find the sum of all transactional resources that should be contained within each block.
Calculate the average amount of resource usage.
if the average is bigger than 20,000 microseconds (0.02 seconds) =>
average = average x 99/100 (average is reduced)
if the average is smaller than 20,000 microseconds (0.02seconds) =>
average = average x 1000/999 (average is increased)
Select bigger one between average or 200K
Select smaller one between selected number from step 3 or 200M => that becomes new "virtual_cpu_limit"
(in other words, the range of virtual_cpu_limit is at the minimum 20K to the maximum 20M)
Now we know why blocktwitter's indiscreet transactions made our CPU Max Limit decrease.
- If the average is bigger than 20,000 microseconds (0.02 seconds)
=> average = average x 99/100 (average is reduced)
In other words, If the sum of all transactions contained within a block is over 0.02 seconds, the next block's CPU Max Limit continues to decrease.
(On the contrary, if the sum of all transactions is below 0.02 seconds, the next block's CPU Max Limit increases.)
By the way, where did the exact time of 0.02 seconds come from?
The standard time of 0.02 seconds is calculated with the global configuration value of max_block_cpu_usage and target_block_cpu_usage_pct.
Standard time = max_block_cpu_usage x target_block_cpu_usage_pct/10,000
Currently, max_block_cpu_usage is set as 200,000 and target_block_cpu_usage_pct is set as 1,000. Therefore,
200,000 x 1,000 / 10,000 = 20,000 microseconds; which is 0.02 seconds.
This global configuration number can be increased or decreased.
Thus, regarding the blocktwitter case, there was actually a simple solution. However, the lack of understanding about EOSIO software caused a problem.
There are still a lot of documents to be created with this kind of problems.
Moreover, not only do block producers need to gain further expertise regarding EOSIO software, but also everyone needs to share and learn from cases such as "blocktwitter".
It is evident that problems will continue to appear over time, but EOS will find the solutions based on community power.