Not sure if the title is poorly worded, but here's what I'm looking to do.

If I have a range of blocks and I want to calculate the hashrate, I can do something similar to what is found here.

To take it a step further, I'd like to be able to calculate hashrate for a given number of blocks from the current block. Using the example provided above, this is rather trivial.

However, I'm running into issues doing this when the difficulty changes somewhere within the range of blocks.

Take last night as an example. Difficulty changed to roughly ~390M. Prior to that it was roughly ~267M.

How would I go about calculating an average network hashrate for a given range where the difficulty has changed within that range?

Thank you for the help!

2 Answers 2


Start by computing the total amount of work. Work is defined as the expected number of hashes that were necessary for a particular block. If a block's target is Target, its amount of work is Work = 2**256 / (Target + 1) (follows from the fact that Target + 1 in 2**256 hashes have a value lower or equal to Target). As the difficulty Diff is defined as MaxTarget / Target with MaxTarget = 65535 * 2**208, it follows that Work = Diff * 2**48 / 65535 = Diff * 4295032833.

So, for each block, look at its difficulty, and compute Diff * 4295032833. Compute the sum of all those values for all blocks in your time range.

Now divide that sum-work by the number of seconds your interval lasted. The result is your average number of hashes per second during that interval.

For very short intervals (less than a few hours), it is possible for block timestamp inaccuracy to be relevant. One way to avoid this problem is by starting off not with a range of blocks, but a range of timestamps, and choosing all blocks within that range, rather than estimating the time range from the range blocks.


You can look at the range's first and last block, if they match exactly you can just calculate the average hash-rate from time elapsed, height difference (number of blocks) and difficulty.

If they don't match, you will have to create the weighted average over each difficulty section. You calculate the average hash-rate for each section then multiply it with the duration, add all the results together, divide by total time.

You could find the sections by binary search between your range's first block and last block, but it would be much easier to just look at every 2016th block, because the reset happens on schedule. ;)

Better yet, you can actually tell immediately that way how many changes in difficulty exist in your range by looking at the height of first and last block.

As pointed out by Pieter, it is possible for blocks to be timestamped inconsistently, making it possible for a block to have a lower timestamp than their predecessor. Any implementation should probably check for corner-cases such as this one. In general the result will be better if a larger interval is taken into account, unless the interval is so large that the hashing-power has increased significantly within it.

  • 1
    This will deal badly with cases where time goes backwards between two blocks. Apr 26, 2014 at 11:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.