Bitcoin Forum
May 06, 2024, 12:14:33 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: How to make sure that difficulty do not go less than 1?  (Read 170 times)
TheWolf666 (OP)
Full Member
***
Offline Offline

Activity: 615
Merit: 154


CEO of Metaisland.gg and W.O.K Corp


View Profile WWW
September 25, 2019, 10:41:25 PM
Last edit: September 25, 2019, 10:54:58 PM by TheWolf666
 #1

I know it might sound stupid because the difficulty of Bitcoin is so high that there is no way it could go less than one.

But, when you fork bitcoin and make some tests, you are usually using just one node to mine. It happens that the difficulty then go lower and lower to even go less than 1.
The division get down to 0.000xxx because the mining gear is not finding hash quick enough.

It can also happen if you want to mimic DigiByte and try to find hashes in a few seconds...instead of 10 minutes.

The code is in CalculateNextWorkRequired

Code:

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
    if (params.fPowNoRetargeting)
        return pindexLast->nBits;

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
    if (nActualTimespan < params.nPowTargetTimespan/2)
        nActualTimespan = params.nPowTargetTimespan/2;
    if (nActualTimespan > params.nPowTargetTimespan*2)
        nActualTimespan = params.nPowTargetTimespan*2;

    // Retarget
    const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
    arith_uint256 bnNew;
    bnNew.SetCompact(pindexLast->nBits);
    bnNew *= nActualTimespan;
    bnNew /= params.nPowTargetTimespan;

    // this is my attempt to limit the difficulty to > 0x1d00ffff but it is not working
    if (bnNew > bnPowLimit)  bnNew = bnPowLimit;
    if (bnNew <0x1d00ffff) bnNew=0x1d00ffff;

    printf("%s  %i\n", bnNew.ToString().c_str(), bnNew.GetCompact());

    return bnNew.GetCompact();
}


In the code I have modified to limit the difficulty to 0x1d00ffff no matter what, but it does not work.
Any clue where I am wrong?

1714954473
Hero Member
*
Offline Offline

Posts: 1714954473

View Profile Personal Message (Offline)

Ignore
1714954473
Reply with quote  #2

1714954473
Report to moderator
1714954473
Hero Member
*
Offline Offline

Posts: 1714954473

View Profile Personal Message (Offline)

Ignore
1714954473
Reply with quote  #2

1714954473
Report to moderator
1714954473
Hero Member
*
Offline Offline

Posts: 1714954473

View Profile Personal Message (Offline)

Ignore
1714954473
Reply with quote  #2

1714954473
Report to moderator
No Gods or Kings. Only Bitcoin
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
achow101
Moderator
Legendary
*
Offline Offline

Activity: 3388
Merit: 6581


Just writing some code


View Profile WWW
September 26, 2019, 04:29:01 AM
Merited by suchmoon (4), bones261 (4), OgNasty (2), LoyceV (2), TheWolf666 (2), hugeblack (1), Heisenberg_Hunter (1), TalkStar (1)
 #2

The numbers there (bnNew, bnPowLimit, etc.) are not the difficulty. The difficulty value that we often see is not directly part of Bitcoin or the blockchain itself. Rather what we see in the blockchain is the target value. The target and difficulty are inversely related, as the target increases, the difficulty decreases. This is because mining works by finding a hash that is less than the target value, so by having  a larger target value, there are more possible valid block hashes and thus a lower difficulty.

The numbers bnNew, bnPowLimit, etc. are all compact representations of the target. This is then expanded out to a full target value that the block hash is compared to. This compact target value is what is included in blocks as the nBits field.

Bitcoin already limits the target to a maximum value which is equal to a difficulty of 1. If the target is that maximum value, its difficulty is said to be 1. This value is not explicitly listed in that function because it is different for mainnet, testnet, and regtest. This value is the variable that has the word powLimit in it. It is defined in src/chainparams.cpp.

There are two things that you are doing wrong: you are doing your limiting incorrectly, and you are doing the limiting after the built in limiter. Firstly, because difficulty decreases as target increases, you need to make the comparison a greater than operator (>) not less than (<) as you have done. If the target is above the maximum target, it needs to be decreased. What you done is set a target minimum, not a difficulty minimum. Look at the line directly above the one you added, that is the built in limiter that is correct. Secondly, you don't need to add your own limiter. Just change the powLimit variable for the correct blockchain in src/chainparams.cpp to the maximum and the limit will be done for you.

In fact, what you are asking has already been done. So I think you just fundamentally misunderstand how the PoW target actually works and what a difficulty of 1 actually looks like.

TheWolf666 (OP)
Full Member
***
Offline Offline

Activity: 615
Merit: 154


CEO of Metaisland.gg and W.O.K Corp


View Profile WWW
September 26, 2019, 03:35:35 PM
Merited by OgNasty (1)
 #3

The numbers there (bnNew, bnPowLimit, etc.) are not the difficulty. The difficulty value that we often see is not directly part of Bitcoin or the blockchain itself. Rather what we see in the blockchain is the target value. The target and difficulty are inversely related, as the target increases, the difficulty decreases. This is because mining works by finding a hash that is less than the target value, so by having  a larger target value, there are more possible valid block hashes and thus a lower difficulty.

The numbers bnNew, bnPowLimit, etc. are all compact representations of the target. This is then expanded out to a full target value that the block hash is compared to. This compact target value is what is included in blocks as the nBits field.

Bitcoin already limits the target to a maximum value which is equal to a difficulty of 1. If the target is that maximum value, its difficulty is said to be 1. This value is not explicitly listed in that function because it is different for mainnet, testnet, and regtest. This value is the variable that has the word powLimit in it. It is defined in src/chainparams.cpp.

There are two things that you are doing wrong: you are doing your limiting incorrectly, and you are doing the limiting after the built in limiter. Firstly, because difficulty decreases as target increases, you need to make the comparison a greater than operator (>) not less than (<) as you have done. If the target is above the maximum target, it needs to be decreased. What you done is set a target minimum, not a difficulty minimum. Look at the line directly above the one you added, that is the built in limiter that is correct. Secondly, you don't need to add your own limiter. Just change the powLimit variable for the correct blockchain in src/chainparams.cpp to the maximum and the limit will be done for you.

In fact, what you are asking has already been done. So I think you just fundamentally misunderstand how the PoW target actually works and what a difficulty of 1 actually looks like.

Thanks for this amazing answer, you are right, I got it wrong and your explanation is really helping me to understand how the target and difficulty are used. Merited +2
You saved me a lot of time trying and testing to find out by myself.
 Kiss

TheWolf666 (OP)
Full Member
***
Offline Offline

Activity: 615
Merit: 154


CEO of Metaisland.gg and W.O.K Corp


View Profile WWW
September 28, 2019, 07:12:50 AM
 #4

I have another question.

If I want the difficulty to increase faster than it decrease, what parameter should I change?

Code:
    if (nActualTimespan < params.nPowTargetTimespan/2)
        nActualTimespan = params.nPowTargetTimespan/2;
    if (nActualTimespan > params.nPowTargetTimespan*2)
        nActualTimespan = params.nPowTargetTimespan*2;

Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!