mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
Implement CalcPastMedianTime
This commit is contained in:
parent
399ce66e5b
commit
7dac149d70
1 changed files with 40 additions and 0 deletions
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
mrand "math/rand"
|
mrand "math/rand"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -59,6 +60,7 @@ const (
|
||||||
blockCacheLimit = 256
|
blockCacheLimit = 256
|
||||||
maxFutureBlocks = 256
|
maxFutureBlocks = 256
|
||||||
maxTimeFutureBlocks = 30
|
maxTimeFutureBlocks = 30
|
||||||
|
medianTimeBlocks = 11
|
||||||
// must be bumped when consensus algorithm is changed, this forces the upgradedb
|
// must be bumped when consensus algorithm is changed, this forces the upgradedb
|
||||||
// command to be run (forces the blocks to be imported again using the new algorithm)
|
// command to be run (forces the blocks to be imported again using the new algorithm)
|
||||||
BlockChainVersion = 3
|
BlockChainVersion = 3
|
||||||
|
|
@ -520,6 +522,37 @@ func (bc *BlockChain) HasBlockAndState(hash common.Hash) bool {
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calcPastMedianTime calculates the median time of the previous few blocks
|
||||||
|
// prior to, and including, the passed block node.
|
||||||
|
//
|
||||||
|
// Modified from btcsuite
|
||||||
|
func (bc *BlockChain) CalcPastMedianTime(number uint64) *big.Int {
|
||||||
|
// Genesis block.
|
||||||
|
if number == 0 {
|
||||||
|
return bc.Genesis().Time()
|
||||||
|
}
|
||||||
|
|
||||||
|
timestamps := make([]*big.Int, medianTimeBlocks)
|
||||||
|
numNodes := 0
|
||||||
|
iterNode := bc.GetBlockByNumber(number)
|
||||||
|
|
||||||
|
ancestors := make(map[common.Hash]*types.Block)
|
||||||
|
for i, ancestor := range bc.GetBlocksFromHash(iterNode.Hash(), medianTimeBlocks) {
|
||||||
|
ancestors[ancestor.Hash()] = ancestor
|
||||||
|
timestamps[i] = ancestor.Time()
|
||||||
|
numNodes++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prune the slice to the actual number of available timestamps which
|
||||||
|
// will be fewer than desired near the beginning of the block chain
|
||||||
|
// and sort them.
|
||||||
|
timestamps = timestamps[:numNodes]
|
||||||
|
sort.Sort(BigIntSlice(timestamps))
|
||||||
|
|
||||||
|
medianTimestamp := timestamps[numNodes/2]
|
||||||
|
return medianTimestamp
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlock retrieves a block from the database by hash and number,
|
// GetBlock retrieves a block from the database by hash and number,
|
||||||
// caching it if found.
|
// caching it if found.
|
||||||
func (self *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
|
func (self *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
|
||||||
|
|
@ -1332,3 +1365,10 @@ func (self *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
|
|
||||||
// Config retrieves the blockchain's chain configuration.
|
// Config retrieves the blockchain's chain configuration.
|
||||||
func (self *BlockChain) Config() *params.ChainConfig { return self.config }
|
func (self *BlockChain) Config() *params.ChainConfig { return self.config }
|
||||||
|
|
||||||
|
// BigIntSlice attaches the methods of sort.Interface to []*big.Int, sorting in increasing order.
|
||||||
|
type BigIntSlice []*big.Int
|
||||||
|
|
||||||
|
func (s BigIntSlice) Len() int { return len(s) }
|
||||||
|
func (s BigIntSlice) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 }
|
||||||
|
func (s BigIntSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue