Closed Xecute0101 closed 4 years ago
There shall be lower and upper bounds for this timestamp factor. Considering 2 for upper bound and 0 for lower bound.
The difficulty algorithm will be modified that it will help to keep the block time as consistent as possible.
You may find something usable here concerning punishing miners for deviation from T https://github.com/seredat/karbowanec/commit/231db5270acb2e673a641a1800be910ce345668a#commitcomment-23983192
I am leaning towards fixing difficulty algo for the efficiency of blockchain instead of controlling the number of blocks:
Joining and synchronizing node can't verify that at the time some block was mined mempool was overcrowded. You can only estimate by taking into account transactions from previous blocks. If transaction count is above median you can lower the difficulty, this way it will be verifiable by the algorithm.
Joining and synchronizing node can't verify that at the time some block was mined mempool was overcrowded. You can only estimate by taking into account transactions from previous blocks. If transaction count is above median you can lower the difficulty, this way it will be verifiable by the algorithm.
So for this, an index of mempool status at the time of the most recent block can be included in the block header blob like an index figure. Is this what you mean?
Yes, but this is an overhead impossible to agree upon and verify, whereas you already have required data that allow you to estimate the demand for transactions - their count in previous blocks. Create a median
of transaction count and use it to adjust difficulty to speedup blocks so you can include transactions faster. But this duplicates the job done by variable block size - if there is demand for transactions block size will grow to accommodate. There's no need to speed up block time.
From the other hand thus you will have two mechanisms to cope with the upsurge of transactions in the case of rapid adoption or usage.
This difficulty adjustment will only activate when total pending tx size is beyond max block size. Now when it is below 1mb(current limit).
Even in case when attackers are posting tons of txs to fill up the mempool and lower difficulty for more block rewards, the proposed changes in block rewards will prevent them from any gains. They will just spend a lot of coins.
Yet this difficulty adjustment will improve the efficiency in handling large amount of traffic. To protect nodes from excessive memory use, using database structure such as RocksDB or LMDB for txs in mempool will definitely improve the overall stability.
Is Basic Block Reward Emission Equation (Abbreviated): (((Total Supply - Previously Emitted Supply) / Emission Factor) - Penalty for Block Size) * ((Timestamp of New Block - Timestamp of Previous Block) / Block Target)
the desired new formula for calculating the next block reward? Or do we have to change the formula again?
we just need to multiply ((timestamp of new block - timestamp of previous block)/blocktarget) to existing reward formula.
I propose to create a variable, called Consistency = ((Timestamp of New Block - Timestamp of Previous Block) / Block Target) and set the minimum and maximum range for this variable between 0 and 2.
@speqtr will work on the implementation.
Updated block reward formula implementation is available in PR #99.
In addition to lower and upper limits (0 and 2) for consistency, I propose to add "smart rounding" for all the values within 0..2 range. This way it will make consistency value more predictable. For example:
Thanks for the input @speqtr.
I think that consistency is just a reflection of what the entire network is doing, So rounding may not be necessary at this point so let's keep that point open to see how network behaves and decide whether to implement rounding or not.
But the number of decimals for consistency may need to be declared. 3 decimal points would be appropriate at the moment, meaning 4th decimal will be rounded to 3rd decimal points.
We need to see how this equation behaves to our current hashrate pattern before deploying. Can you please check? @nnian
@nnian I can see that PR #99 was merged first and then instantly reverted (removed from master
branch). Do I need to reopen it? Or will you manually re-add changes from PR #99 later?
Maybe you'll open it again and we'll discuss my concerns? With an implementation of a update height. What do you think about? I had commented on your PR a few times just a few minutes ago.
@nnian later today I'll open new PR with the same changes as in PR #99 so we could add "activation height" for new block reward formula and then merge it once again.
Okay, sounds great. I think we shouldn't change the block reward without the assurance that every user has the same daemon version.
New PR containing updated block reward formula is available. PR #101.
What this change entails...
The above graph shows how block reward emission has been for all PoWs. Heavily relying on difficulty to get to that green zone to make the block time and thereby block reward consistent. Miners were able to attack block rewards by utilizing massive hashrate to find blocks in a short period of time.
EPoSe PoW will change this like above graph with a maximum cap up to 2X normal rewards for longer solve time but almost zero block rewards in case of any timestamp attacks by posting many blocks in a short period of time.
With this solution in place, miners will be awarded proportionally to their contribution time to QWC blockchain. Also the block reward emission will be consistent over time. This "time" is the essence of all EPoSe implementations.
Difficulty algo is based on expectation based on previous history whereas this block reward algo is based on the results miners post. Diff algo is very difficult or almost impossible to be precise when there are sudden changes in miners' behavior. EPoSe block reward algo will tame this side effect in short.
This is a major step in order to make PoW part of EPoSe(Egalitarian Proof of Service) fair for all miners and users.
Thanks for the work and I think we can close this issue until we have a problem from this change.
Thanks for the work and I think we can close this issue until we have a problem from this change.
@Xecute0101 Hopefully, we won't have any problems with this change 🙂
This makes miners to forge timestamps as close to target as possible to get max reward. The way CN pools operate they are not ready for this, they normally prepare block template with timestamp once and issue it to miners to hash, therefore every CN block has timestamp like one block behind (close to prev. block real solution time). This is easy to fix in pool software (in modified daemon in fact), instead of current timestamp during block template creation they will use prev block timestamp + target. Some fast and large miner may forge timestamps ahead from real time hitting FTL limit, I don't know what happens then and for other honest miners. What happens if miner forges timestamp ahead and then honest miner's solve time becomes negative?
Let's try to make a small change to the equation.
Previously, the most recent change in the formula is like this.
If consistency is less than equal to 1,
New Basic Block Reward Emission Equation (Abbreviated) = Basic Block Reward Emission Equation (previous equation) x consistency
=> If they solve the block too quickly with less effort, miners will get proportionally less rewards. So no more luck factor. If miners try to forge timestamps of blocks close to each other to get more block rewards, they will be penalized.
Else if consistency is greater than 1 and if ((difficulty windows * difficulty target) - (total timestamp difference for the duration of difficulty windows)) is greater than or equal to 0,
Basic Block Reward Emission Equation (previous equation) x maximum between consistency or (1+ min.((((difficulty windows * difficulty target) - (total timestamp difference for the duration of difficulty windows))/(difficulty target))), 1)
=> If miners or pools try to forge the timestamp before pool operates, it will be compared to range of block's timestamp to see how much time gap there is to allow additional reward. This is the solution for honest miners.
Else if consistency is greater than 1 and if ((difficulty windows * difficulty target) - (total timestamp difference for the duration of difficulty windows)) is less than 0,
Basic Block Reward Emission Equation (previous equation) x 0.0001
=> If miners or pools try to forge the timestamp before pool operates, it will be compared to range of block's timestamp to see how much time gap there is to allow additional reward. If they go over the range of time then all miners will be penalized. So this will force miners and pools to correct the timestamp forging.
In case the hashrate is actually dropping due to less popularity or network issue, this part of equation will not cause any harmful effect as the issuance of new coins will be restricted until the network finds the new equilibrium.
If some miner forge timestamp and the honest miner finds it faster, then miner who forge timestamp will get orphan block. There is really no incentive for them to try to do this. They may succeed in a block or two but will fail shortly after. This may not be the perfect fix but it will serve its purpose for the time being.
Zawy, the difficulty algo dev mentioned this in PR #99 that
But make sure out of sequence timestamps are handled correctly:
// Safely handle out-of-sequence timestamps if ( timestamps[i] >= previous_timestamp ) { this_timestamp = timestamps[i]; } else { this_timestamp = previous_timestamp+1; }
Do we have this measure in place? If not, we should. @speqtr @Sw0rdf1sh1 @nnian
@Xecute0101 I think we have no time to rewrite this PR again and again if we want to have the new reward formula up to network height 400,000. in 24k blocks would be the change. We still need time to create the new wallets, to distribute them and, if necessary, to provide assistance while every user update to this new wallet in time.
We should think about it.
Version 5.2.0 has been merged with the PR 101 in the master for 18 days now. The new Chinese Exchanges may already use this version. Also some pools have already changed. We have to decide soon. But we don't have time to change this formula just a few blocks before that soft fork date.
We should provide new wallets at least 14 days before we reach height 400k. I don't know what happens when there are different reward formulas available on the network and especially in various pools. We need a network with the same software version.
If there is a potential problem or even some minor changes with this merged calculation formula, I have to postpone and increase the Softfork height, revert version 5.2.0 and we need to provide 5.2.1 version and inform exchanges, pools, node owner and wallet user to update again to 5.2.1. After this we can talk about this formula and change whatever we want.
@nnian , Thanks for your opinion on this improvement.
I suggest we postpone this until block height 500,000. I hope that we can settle issues with all desktop and mobile wallets by block height 500,000 and move on with EPoSe implementation.
Had run a node that activated this at the height of 500,000 and this is the message we get.
2020-Feb-11 19:10:20.936531 INFO
[checkpoints] CHECKPOINT PASSED FOR HEIGHT 500000 432b0c6cfbb5967950efc2f2358f42dc85ddbc5dd270b619cd1f466970a41236
2020-Feb-11 19:10:20.936531 ERROR [Blockchain] Coinbase transaction spend too much money: 135845.06483386, block reward is 0.00000000
The gap between height 499,999 and 500,000 was about 67 seconds. So, if we did correct implementation of the formula, the block reward error should show that the reward should be
new reward = 135845.06483386 * consistency(which is 67sec/120sec) = 75,846.82786557
So it should be showing the following error message when correctly implemented,
2020-Feb-11 19:10:20.936531 ERROR [Blockchain] Coinbase transaction spend too much money: 135845.06483386, block reward is 75,846.82786557
bool Currency::getBlockReward(
uint8_t blockMajorVersion,
size_t medianSize,
size_t currentBlockSize,
uint64_t alreadyGeneratedCoins,
uint64_t fee,
uint64_t &reward,
int64_t &emissionChange,
uint32_t height,
uint64_t blockTarget) const
{
assert(alreadyGeneratedCoins <= m_moneySupply);
assert(m_emissionSpeedFactor > 0 && m_emissionSpeedFactor <= 8 * sizeof(uint64_t));
// Tail emission
uint64_t baseReward = (m_moneySupply - alreadyGeneratedCoins) >> m_emissionSpeedFactor;
if (alreadyGeneratedCoins + CryptoNote::parameters::TAIL_EMISSION_REWARD >= m_moneySupply
|| baseReward < CryptoNote::parameters::TAIL_EMISSION_REWARD) {
baseReward = CryptoNote::parameters::TAIL_EMISSION_REWARD;
}
size_t blockGrantedFullRewardZone = blockGrantedFullRewardZoneByBlockVersion(blockMajorVersion);
medianSize = std::max(medianSize, blockGrantedFullRewardZone);
if (currentBlockSize > medianSize * UINT64_C(2)) {
logger(TRACE)
<< "Block cumulative size is too big: "
<< currentBlockSize
<< ", expected less than "
<< medianSize * UINT64_C(2);
return false;
}
uint64_t penalizedBaseReward = getPenalizedAmount(baseReward, medianSize, currentBlockSize);
uint64_t penalizedFee = fee;
if (blockMajorVersion >= BLOCK_MAJOR_VERSION_2 || cryptonoteCoinVersion() == 1) {
penalizedFee = getPenalizedAmount(fee, medianSize, currentBlockSize);
}
double consistency = 1.0;
if (height >= CryptoNote::parameters::UPGRADE_HEIGHT_REWARD_SCHEME && difficultyTarget() != 0) {
// blockTarget is (Timestamp of New Block - Timestamp of Previous Block)
consistency = blockTarget / difficultyTarget();
// consistency range is 0..2
consistency = std::max<double>(consistency, 0.0);
consistency = std::min<double>(consistency, 2.0);
}
double penalizedReward = static_cast<double>(penalizedBaseReward + penalizedFee);
emissionChange = penalizedBaseReward - (fee - penalizedFee);
reward = static_cast<uint64_t>(penalizedReward * consistency);
return true;
}
Besides this error you probably should fix emissionChange
so it takes into account new penalizedReward
not penalizedBaseReward
.
Perhaps need to cast in consistency = blockTarget / difficultyTarget();
like consistency = (double)blockTarget / (double)difficultyTarget();
@speqtr @exploshot @nnian thought?
Also, the controversial part is going to interfere when we get to tail emission. assert(alreadyGeneratedCoins <= m_moneySupply); @speqtr erased and it kinda raise a flag but it was a right decision.
Yes, it should be deleted
where are this penalizedReward
and reward
variables used? only declared here maybe?
penalizedReward
is used in this function to calculate final reward
, but emissionChange is also used elsewhere so it is important that it returns the correct value.
@Xecute0101 @aivve I can implement discussed changes and open a new PR, so we could continue dicussing and testing proposed changes at the same time 🙂
I just realized that you probably are making totally different scheme than I thought, the one that was also suggested by @zawy12 - if the solve time
is smaller than target time
then reward
is proportionally smaller AND vice versa - if solve time
is longer, then reward
is bigger. @Xecute0101 this then changes the incentives for miners to artificially create as long gaps as they could to maximize the reward. Of course, they will hit the FTL limit how far timestamp can go into the future and you then should really tighten that limit. (I thought that you are going to punish miners for deviation from target solve time in ANY direction so they will be incetivized to keep solve times as close to target as possible).
Yes, we talked about this. The reward gets bigger if they miners mine longer in a sense. Have to look into FTL and Difficulty Algo now. Unless I find a way to distribute hashpower equally among parties.
Just tighten the limits so they can't fake timestamps.
We need to get this calculation right, first I think. If anyone of you is going to test this, change the height in the config and try to see the error msg displays correct rewards.
Also originally doubles were avoided in CryptoNote... Perhaps find a way to calculate this using integer math.
Increasing reward based on solvetime has the same effect as decreasing difficulty. Miners are only interested in getting the highest reward/difficulty ratio.
Another option I've been thinking about (that deadalnix and jl777 like) actually depends on on-off mining. The idea is that your dedicated miners can be identified as being the ones who are still mining when the difficulty is high. Ostensibly, they will not attack the coin and you want them to win in a chain race. They paid a higher price in the past so give them something extra to win chain races. As an example plan, if difficulty is more than 1 std deviation (16% of blocks) above the 1 day average, then credit the miner's output address with 1/2 of the above-average difficulty. This can be thought of as a 2nd coin that can't be sent to any other address. If there is a battle between 2 or more tips with at least 3 blocks each, then miners with this coin saved up from the past can use it to artificially lower difficulty to win a chain race. They can "get back" 1/2 of the excess difficulty they spent on blocks that were in the the upper 16% of difficulties. It specifically is NOT meant to motivate the mining of higher difficulty. We want higher difficulty so that we can identify our friends, and let them win chain races. A limit might be placed on the amount of "credit" they can get, and the credit might deteriorate over a year. So if you have 10% of your miners really dedicated, and 16% of your difficulty swings everyday are 20% too high, then that 10% of miners are getting 16% / 2 * 20% = 1.6% of the day's chain work back as credit. In 100 days they will 160% of a days chain work to fight attacks.
I need to do an issue-article on this.
Yes, it should be deleted
Or just in case, commenting out the line would be okay too.
2020-Feb-12 15:50:23.631190 ERROR Coinbase transaction spend too much money: 135845.06483386, block reward is 67922.53241693
This happened when consistency was not used and I wanted to test out where to put this consistency variable. It just happens to be right after baseReward. I just did "*0.5" like this.
uint64_t baseReward = ((m_moneySupply - alreadyGeneratedCoins) >> m_emissionSpeedFactor) * 0.5;
bool Currency::getBlockReward(
uint8_t blockMajorVersion,
size_t medianSize,
size_t currentBlockSize,
uint64_t alreadyGeneratedCoins,
uint64_t fee,
uint64_t &reward,
int64_t &emissionChange,
uint32_t height,
uint64_t blockTarget) const
{
assert(alreadyGeneratedCoins <= m_moneySupply);
assert(m_emissionSpeedFactor > 0 && m_emissionSpeedFactor <= 8 * sizeof(uint64_t));
// Consistency
double consistency = 1.0;
if (height >= CryptoNote::parameters::UPGRADE_HEIGHT_REWARD_SCHEME && difficultyTarget() != 0) {
// blockTarget is (Timestamp of New Block - Timestamp of Previous Block)
consistency = blockTarget / difficultyTarget();
// consistency range is 0..2
consistency = std::max<double>(consistency, 0.0);
consistency = std::min<double>(consistency, 2.0);
}
// Tail emission
uint64_t baseReward = ((m_moneySupply - alreadyGeneratedCoins) >> m_emissionSpeedFactor) * 0.5;
if (alreadyGeneratedCoins + CryptoNote::parameters::TAIL_EMISSION_REWARD >= m_moneySupply
|| baseReward < CryptoNote::parameters::TAIL_EMISSION_REWARD) {
baseReward = CryptoNote::parameters::TAIL_EMISSION_REWARD;
}
size_t blockGrantedFullRewardZone = blockGrantedFullRewardZoneByBlockVersion(blockMajorVersion);
medianSize = std::max(medianSize, blockGrantedFullRewardZone);
if (currentBlockSize > medianSize * UINT64_C(2)) {
logger(TRACE)
<< "Block cumulative size is too big: "
<< currentBlockSize
<< ", expected less than "
<< medianSize * UINT64_C(2);
return false;
}
uint64_t penalizedBaseReward = getPenalizedAmount(baseReward, medianSize, currentBlockSize);
uint64_t penalizedFee = fee;
if (blockMajorVersion >= BLOCK_MAJOR_VERSION_2 || cryptonoteCoinVersion() == 1) {
penalizedFee = getPenalizedAmount(fee, medianSize, currentBlockSize);
}
uint64_t penalizedReward = static_cast<uint64_t>(penalizedBaseReward + penalizedFee);
emissionChange = penalizedReward - fee;
reward = static_cast<uint64_t>(penalizedReward);
return true;
I also tried to multiply consistency in place of 0.5, then the block reward was 0.0000000000. This means that the consistency is returning 0.
2020-Feb-13 07:01:37.370251 ERROR Coinbase transaction doesn't use full amount of block reward: spent 135845.06483386, block reward is 16301407.78006320
Above happens when difficultyTarget() is multiplied in place of 0.5 meaning the value of difficultyTarget() is 120 and it is returning value properly.
2020-Feb-13 07:05:48.258607 ERROR Coinbase transaction doesn't use a full amount of block reward: spent 135845.06483386, block reward is 9101619.34386862
Above happens when blockTarget() is multiplied in place of 0.5 meaning the value of blockTarget() is 67 and it is returning value properly.
When Coinbase transaction is less than reward (minerReward<reward), following msg should be displayed per Blockchain::validate_miner_transaction() in Blockchain.cpp file.
if (minerReward > reward) {
logger(ERROR, BRIGHT_RED)
<< "Coinbase transaction spend too much money: " << m_currency.formatAmount(minerReward)
<< ", block reward is " << m_currency.formatAmount(reward);
2020-Feb-13 07:15:41.977399 ERROR Coinbase transaction spend too much money: 135845.06483386, block reward is 75846.82786557
The above happens when the following code changed.
consistency = (double)blockTarget / (double)difficultyTarget();
uint64_t baseReward = ((m_moneySupply - alreadyGeneratedCoins) >> m_emissionSpeedFactor) * consistency;
When Coinbase transaction is greater than reward (minerReward>reward), the following msg should be displayed per Blockchain::validate_miner_transaction() in Blockchain.cpp file.
else if (minerReward < reward) {
logger(ERROR, BRIGHT_RED)
<< "Coinbase transaction doesn't use full amount of block reward: spent "
<< m_currency.formatAmount(minerReward)
<< ", block reward is "
<< m_currency.formatAmount(reward);
Correct messages were displayed from the examples of previous comment.
The working code looks like
bool Currency::getBlockReward(
uint8_t blockMajorVersion,
size_t medianSize,
size_t currentBlockSize,
uint64_t alreadyGeneratedCoins,
uint64_t fee,
uint64_t &reward,
int64_t &emissionChange,
uint32_t height,
uint64_t blockTarget) const
{
// assert(alreadyGeneratedCoins <= m_moneySupply);
assert(m_emissionSpeedFactor > 0 && m_emissionSpeedFactor <= 8 * sizeof(uint64_t));
// Consistency
double consistency = 1.0;
if (height >= CryptoNote::parameters::UPGRADE_HEIGHT_REWARD_SCHEME && difficultyTarget() != 0) {
// blockTarget is (Timestamp of New Block - Timestamp of Previous Block)
consistency = (double) blockTarget / (double) difficultyTarget();
// consistency range is 0..2
consistency = std::max<double>(consistency, 0.0);
consistency = std::min<double>(consistency, 2.0);
}
// Tail emission
uint64_t baseReward = ((m_moneySupply - alreadyGeneratedCoins) >> m_emissionSpeedFactor) * consistency;
if (alreadyGeneratedCoins + CryptoNote::parameters::TAIL_EMISSION_REWARD >= m_moneySupply
|| baseReward < CryptoNote::parameters::TAIL_EMISSION_REWARD) {
baseReward = CryptoNote::parameters::TAIL_EMISSION_REWARD;
}
size_t blockGrantedFullRewardZone = blockGrantedFullRewardZoneByBlockVersion(blockMajorVersion);
medianSize = std::max(medianSize, blockGrantedFullRewardZone);
if (currentBlockSize > medianSize * UINT64_C(2)) {
logger(TRACE)
<< "Block cumulative size is too big: "
<< currentBlockSize
<< ", expected less than "
<< medianSize * UINT64_C(2);
return false;
}
uint64_t penalizedBaseReward = getPenalizedAmount(baseReward, medianSize, currentBlockSize);
uint64_t penalizedFee = fee;
if (blockMajorVersion >= BLOCK_MAJOR_VERSION_2 || cryptonoteCoinVersion() == 1) {
penalizedFee = getPenalizedAmount(fee, medianSize, currentBlockSize);
}
emissionChange = penalizedBaseReward - (fee - penalizedFee);
reward = penalizedBaseReward + penalizedFee;
return true;
}
@nnian @exploshot @speqtr @aivve
Added #include <cmath>
and double exponent = 0.25;
and changed consistency formula when it is above 1.
bool Currency::getBlockReward(
uint8_t blockMajorVersion,
size_t medianSize,
size_t currentBlockSize,
uint64_t alreadyGeneratedCoins,
uint64_t fee,
uint64_t &reward,
int64_t &emissionChange,
uint32_t height,
uint64_t blockTarget) const
{
// assert(alreadyGeneratedCoins <= m_moneySupply);
assert(m_emissionSpeedFactor > 0 && m_emissionSpeedFactor <= 8 * sizeof(uint64_t));
// Consistency
double consistency = 1.0;
double exponent = 0.25;
if (height >= CryptoNote::parameters::UPGRADE_HEIGHT_REWARD_SCHEME && difficultyTarget() != 0) {
// blockTarget is (Timestamp of New Block - Timestamp of Previous Block)
consistency = (double) blockTarget / (double) difficultyTarget();
// consistency range is 0..2
if (consistency < 1.0) {
consistency = std::max<double>(consistency, 0.0);
}
else if (consistency > 1.0) {
consistency = pow(consistency, exponent);
consistency = std::min<double>(consistency, 2.0);
}
else {
consistency = 1.0;
}
}
// Tail emission
uint64_t baseReward = ((m_moneySupply - alreadyGeneratedCoins) >> m_emissionSpeedFactor) * consistency;
if (alreadyGeneratedCoins + CryptoNote::parameters::TAIL_EMISSION_REWARD >= m_moneySupply
|| baseReward < CryptoNote::parameters::TAIL_EMISSION_REWARD) {
baseReward = CryptoNote::parameters::TAIL_EMISSION_REWARD;
}
size_t blockGrantedFullRewardZone = blockGrantedFullRewardZoneByBlockVersion(blockMajorVersion);
medianSize = std::max(medianSize, blockGrantedFullRewardZone);
if (currentBlockSize > medianSize * UINT64_C(2)) {
logger(TRACE)
<< "Block cumulative size is too big: "
<< currentBlockSize
<< ", expected less than "
<< medianSize * UINT64_C(2);
return false;
}
uint64_t penalizedBaseReward = getPenalizedAmount(baseReward, medianSize, currentBlockSize);
uint64_t penalizedFee = fee;
if (blockMajorVersion >= BLOCK_MAJOR_VERSION_2 || cryptonoteCoinVersion() == 1) {
penalizedFee = getPenalizedAmount(fee, medianSize, currentBlockSize);
}
emissionChange = penalizedBaseReward - (fee - penalizedFee);
reward = penalizedBaseReward + penalizedFee;
return true;
}
For mining rewards over 120 seconds, double exponent = 0.25;
is used for raising consistency to a power of (1/4). The impact of this is shown in the attached excel file. EPoW.Worksheet R0.xlsx
Any extra time over difficulty target(120 sec) will get additional reward but does not provide enough incentives to forge a timestamp beyond the real time because it yields less profit than mining a next block less than 120 seconds.
The significance of QWC's EPoW is that it is a completely independent approach to influence miners' behaviors from difficulty adjustments and an egalitarian reward system to all mining environments.
I think we are ready to commit this to our main repo. Any devil's advocate? @nnian @speqtr @aivve @zawy12 @exploshot
This is the first proposal to change our reward system for Qwertycoin Network.
Purpose: Qwertycoin aims to incentivize/disincentivize the network through a systematic approach by adjusting equations related to block reward calculations.
Current Status:
Proposed Change:
Premises:
Implications of This Change: