GetMedianTimePast: Can it be optimized with a simple index - 5? #18833

issue sondreb openend this issue on April 30, 2020
  1. sondreb commented at 5:20 pm on April 30, 2020: none

    I was working on an blockchain indexer and explorer, and as I was trying to figure out how to calculate the returned “medianTime” from the “getblockchaininfo”, I realized that the value is not what I was expecting it to be.

    This was in an C# implementation of similar code to Bitcoin, so I initially thought it was a bug in the .NET implementation. Then I had a look at the C++ implementation and to me it appears to be the same.

     0    static constexpr int nMedianTimeSpan = 11;
     1
     2    int64_t GetMedianTimePast() const
     3    {
     4        int64_t pmedian[nMedianTimeSpan];
     5        int64_t* pbegin = &pmedian[nMedianTimeSpan];
     6        int64_t* pend = &pmedian[nMedianTimeSpan];
     7
     8        const CBlockIndex* pindex = this;
     9        for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
    10            *(--pbegin) = pindex->GetBlockTime();
    11
    12        std::sort(pbegin, pend);
    13        return pbegin[(pend - pbegin)/2];
    14    }
    

    From what I can understand, the method loops backwards through the blocks from the current block, populates the block time into an array, sort it (it’s already sorted), then picks the middle one (5) and returns that.

    Is that correctly assumed?

    Wouldn’t simply selecting index - 5 do the exact same thing? Of course one would need to calculate for genesis and the first 10 blocks, but that’s easy.

    I was expecting this method to do something else, namely take the diff time (not the timestamp) between each block, then picking the middle one, which would give the average time between each block for the last 10 blocks. Another quick way to calculate, would be take GetBlockTime from the block 10 indexes back, diff with current block and divide by 10, should give one type of average.

    The current code populates an array of 10 timestamps, but it only picks the one in the middle. There is no reason to populate it with 10 timestamps, as the 5 oldest are not used for anything. It also doesn’t use or calculate/care about any of the other blocks.

    So if the last 5 blocks took:

    1 hour 10 minutes 10 minutes 10 minutes 10 minutes 10 minutes 10 minutes 10 minutes 10 minutes 10 minutes

    Then GetMedianTimePast will return a timestamp 1 hour and 40 minutes back in time from current block. I understand median is correct name for the method (it returns the middle of the sorted numbers), but is the numbers to be sorted suppose to be time between blocks (datediff) and not the actual timestamps?

    The “medianTime” returned is also not the time between blocks, it is the time 5 blocks back. Which is why I’m wondering why not simply grab the datetime of the block 5 indexes back instead?

    For for me to show the median time between blocks in the block explorer, I must take (BlockTime - MedianTime / 5). From what I know, I think the calculate is used for consensus/mining, and not suppose to be what I’m after (average block time), I can calculate that another way, but I stumbled upon this and initially thought it to be something else, and thought it could maybe be improved a bit?

    Is that the way it is suppose to work, or am I not able to read the code properly? Thanks!

  2. sondreb added the label Feature on Apr 30, 2020
  3. MarcoFalke commented at 5:24 pm on April 30, 2020: member

    it’s already sorted

    Why would it be sorted? Miners can pick the value to their liking, as long as it conforms to BIP 113

  4. MarcoFalke closed this on Apr 30, 2020

  5. MarcoFalke removed the label Feature on Apr 30, 2020
  6. MarcoFalke added the label Consensus on Apr 30, 2020
  7. MarcoFalke added the label Questions and Help on Apr 30, 2020
  8. DrahtBot locked this on Feb 15, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-11-21 15:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me