Post
Topic
Board Development & Technical Discussion
Merits 4 from 1 user
Re: Requesting Testnet4 tBTC
by
garlonicon
on 29/12/2024, 13:49:39 UTC
⭐ Merited by BlackHatCoiner (4)
Quote
I still don't understand how they get their difficulty, though.
I guess they just call "getblocktemplate".

1. If block_time > last_block_time+1200, then difficulty=1
2. Otherwise, difficulty=network_diff

Note that every miner can control "block_time", because it is just what is put in block header. By default, Bitcoin Core gives you the earliest time (based on the current time, the MTP rule, and the timewarp 600 seconds rule). But: you can put some later timestamp there, to trigger "difficulty=1" condition.

Quote
but how do they know which value to put in their blocks, beforehand?
There are only two options: the network difficulty, and the minimal difficulty. If you want to get the network difficulty, then just check the latest block, where it was adjusted.
Code:
block_number=60942
60942/2016=30+...
30*2016=60480 //latest adjustment
bits_in_block(60480)=0x1913e3b7
bits_to_target(0x1913e3b7)=0000000000000013e3b700000000000000000000000000000000000000000000
bits_to_target(0x1d00ffff)=00000000ffff0000000000000000000000000000000000000000000000000000
difficulty=00000000ffff0000000000000000000000000000000000000000000000000000/0000000000000013e3b700000000000000000000000000000000000000000000
difficulty=26959535291011309493156476344723991336010898738574164086137773096960/124848484694520496450254989037678616522135653265297473798144
difficulty=215938025+81833825167668903265531020299488556990381026556677309071360/124848484694520496450254989037678616522135653265297473798144
difficulty=215938025+(2^176*3*5*7*79*103/2^176*3^3*23*2099)
difficulty=215938025+284795/434493
difficulty=215938025.6554651053066447560720195722370671104022389313521736828901731443...
But, miners are not calculating "0x1913e3b7" for every block. They can do it just once per 2016 blocks.

https://github.com/bitcoin/bitcoin/blob/master/src/pow.cpp#L14
Code:
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
    assert(pindexLast != nullptr);
    unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();

    // Only change once per difficulty adjustment interval
    if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
    {
        if (params.fPowAllowMinDifficultyBlocks)
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Go back by what we want to be 14 days worth of blocks
    int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
    assert(nHeightFirst >= 0);
    const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
    assert(pindexFirst);

    return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
}
See? This "CalculateNextWorkRequired" function is called only every 2016 blocks. In all other cases, the code is just copy-pasting "nBits" from the nearest block header, which contained the real network difficulty.

Quote
Does that mean that if it's shown as 210M, it's 6 times easier to mine it?
Well, if you have for example 336 ASIC-mined blocks, and 1680 CPU-mined blocks, when you explore the latest 2016 blocks, then having 336 blocks with 216M gives you the same chainwork, as 2016 blocks, mined with 36M. Because during difficulty adjustments, all that is counted, is just "how fast the last 2016 blocks were mined", and not "how many hashes were needed to do that".

Quote
if we took these ASIC miners and started a new Bitcoin network, with mainnet rules, would difficulty reach 210M / 6 =  35M?
Exactly. Initially, you have a network with all ASICs, where 100% blocks are honestly mined. Then, when CPU miners abuse 20 minutes rule, it means 2016 blocks are produced faster, than they would be in 100% ASIC world. So, the difficulty is increased, and in the next two weeks, ASICs can produce even less blocks. And that situation keeps repeating, as long as other limits are not reached. And then, the difficulty put in ASIC blocks no longer reflect, what they can mine during 10 minutes.