4

What is the correct way to estimate blocks time generation for chain with Web3?

4 Answers 4

6

Because we know block times do not overlap the easiest approach (taking only 3 queries). Just grab the current block and a block X blocks before the current block, subtract the time of the old block from the new block. That will give you how long it took for X blocks. Dived that by X to get the average time per block.

So here with X = 500

  var nowBlock;
  // Get the current block number
  web3.eth.getBlockNumber(function(err, nowBlockNumber) {
    // Get the current block
    web3.eth.getBlock(nowBlockNumber, function(err, nb) {
      nowBlock = nb;
      // Get the block 500 blocks ago
      web3.eth.getBlock(nowBlockNumber - 500, function(err, thenBlock) {
        // Take the average of the then and now timestamps
        KTC.averageBlockTime = (nowBlock.timestamp - thenBlock.timestamp) / 500.0;
      });
    });
  });
1
  • 1
    var avg = ((await web3.eth.getBlock(block)).timestamp - (await web3.eth.getBlock(block - 500)).timestamp) / 500; Oct 16, 2021 at 11:05
2

Here's a version expanded from Viktor Baranov's answer that takes the average of the last 100 blocks.

const getBlockAverageTime = async () => {
  const span = 100
  const times = []
  const currentNumber = await web3.eth.getBlockNumber()
  const firstBlock = await web3.eth.getBlock(currentNumber - span)
  let prevTimestamp = firstBlock.timestamp

  for (let i = currentNumber - span + 1; i <= currentNumber; i++) {
    const block = await web3.eth.getBlock(i)
    let time = block.timestamp - prevTimestamp
    prevTimestamp = block.timestamp
    times.push(time)
  }

  return Math.round(times.reduce((a, b) => a + b) / times.length)
}
0
calculateBlockTimeGeneration(web3, function(err, blockTimeGeneration) {
    if (err) return console.log(err);
    console.log("Block time generation in seconds: " + blockTimeGeneration);
});


function calculateBlockTimeGeneration(web3, cb) {
    web3.eth.getBlockNumber(function(err, curBlock) {
        if (err) return cb(err);
        let prevBlock = curBlock - 1;
        let prevBlockInfo = web3.eth.getBlock(prevBlock);
        let curBlockInfo = web3.eth.getBlock(curBlock);
        let blockTimeGeneration = curBlockInfo.timestamp - prevBlockInfo.timestamp;
        cb(null, blockTimeGeneration);
    });
}

Please, post your answer, if it could be made easier.

2
  • 2
    The block times have pretty high variance, so I'd consider taking the average block time of many blocks before. Also, there will be sharp changes at key upgrades like Metropolis, part 2.
    – carver
    Aug 17, 2017 at 17:20
  • 1
    This is only the time between the latest block and the previous one. It could vary widely from one pair of blocks to the next. The value of interest would be the average block generation time - average either over a certain time period or average over a number of blocks. I guess the calculateBlockTimeGeneration function could be modified to look at the last N blocks instead of just the previous one, and take an average of the time difference between each consecutive block pair. Aug 17, 2017 at 17:27
0

I wrote two Medium articles (here and here) that looked at block production per week.

Looking at how many blocks are produced over a constant amount of "real-world" time is revelatory. The effect of the difficulty bomb (even it's double nature) become obvious.

All I really did was scan the block timestamps and whenever it was Sunday morning at 12:00 midnight, I printed out the block number since the previous Sunday morning at midnight and their differences to get blocks/week.

Your Answer

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

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