aboutsummaryrefslogtreecommitdiffstats
path: root/core/chain_manager.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-06-16 18:41:50 +0800
committerJeffrey Wilcke <geffobscura@gmail.com>2015-06-30 00:51:47 +0800
commit1d42888d3047dabfb352c94a2051e7af14d2a509 (patch)
tree8ca68ca98bd697f26f2033a5480e78ccbf064162 /core/chain_manager.go
parent654564e164b3b6f7f4ba1e8bbd6fcd64776068fa (diff)
downloadgo-tangerine-1d42888d3047dabfb352c94a2051e7af14d2a509.tar.gz
go-tangerine-1d42888d3047dabfb352c94a2051e7af14d2a509.tar.zst
go-tangerine-1d42888d3047dabfb352c94a2051e7af14d2a509.zip
core/types: make blocks immutable
Diffstat (limited to 'core/chain_manager.go')
-rw-r--r--core/chain_manager.go94
1 files changed, 28 insertions, 66 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 3b9b7517b..8a79e3e8a 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -38,23 +38,24 @@ const (
maxTimeFutureBlocks = 30
)
-func CalcDifficulty(block, parent *types.Header) *big.Int {
+// CalcDifficulty is the difficulty adjustment algorithm. It returns
+// the difficulty that a new block b should have when created at time
+// given the parent block's time and difficulty.
+func CalcDifficulty(time int64, parentTime int64, parentDiff *big.Int) *big.Int {
diff := new(big.Int)
-
- adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor)
- if big.NewInt(int64(block.Time)-int64(parent.Time)).Cmp(params.DurationLimit) < 0 {
- diff.Add(parent.Difficulty, adjust)
+ adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
+ if big.NewInt(time-parentTime).Cmp(params.DurationLimit) < 0 {
+ diff.Add(parentDiff, adjust)
} else {
- diff.Sub(parent.Difficulty, adjust)
+ diff.Sub(parentDiff, adjust)
}
-
if diff.Cmp(params.MinimumDifficulty) < 0 {
return params.MinimumDifficulty
}
-
return diff
}
+// CalcTD computes the total difficulty of block.
func CalcTD(block, parent *types.Block) *big.Int {
if parent == nil {
return block.Difficulty()
@@ -62,6 +63,8 @@ func CalcTD(block, parent *types.Block) *big.Int {
return new(big.Int).Add(parent.Td, block.Header().Difficulty)
}
+// CalcGasLimit computes the gas limit of the next block after parent.
+// The result may be modified by the caller.
func CalcGasLimit(parent *types.Block) *big.Int {
decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor)
contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3))
@@ -71,11 +74,11 @@ func CalcGasLimit(parent *types.Block) *big.Int {
gl := new(big.Int).Sub(parent.GasLimit(), decay)
gl = gl.Add(gl, contrib)
gl = gl.Add(gl, big.NewInt(1))
- gl = common.BigMax(gl, params.MinGasLimit)
+ gl.Set(common.BigMax(gl, params.MinGasLimit))
if gl.Cmp(params.GenesisGasLimit) < 0 {
- gl2 := new(big.Int).Add(parent.GasLimit(), decay)
- return common.BigMin(params.GenesisGasLimit, gl2)
+ gl.Add(parent.GasLimit(), decay)
+ gl.Set(common.BigMin(gl, params.GenesisGasLimit))
}
return gl
}
@@ -255,50 +258,11 @@ func (bc *ChainManager) makeCache() {
bc.cache = NewBlockCache(blockCacheLimit)
}
// load in last `blockCacheLimit` - 1 blocks. Last block is the current.
- ancestors := bc.GetAncestors(bc.currentBlock, blockCacheLimit-1)
- ancestors = append(ancestors, bc.currentBlock)
- for _, block := range ancestors {
+ for _, block := range bc.GetBlocksFromHash(bc.currentBlock.Hash(), blockCacheLimit) {
bc.cache.Push(block)
}
}
-// Block creation & chain handling
-func (bc *ChainManager) NewBlock(coinbase common.Address) *types.Block {
- bc.mu.RLock()
- defer bc.mu.RUnlock()
-
- var (
- root common.Hash
- parentHash common.Hash
- )
-
- if bc.currentBlock != nil {
- root = bc.currentBlock.Header().Root
- parentHash = bc.lastBlockHash
- }
-
- block := types.NewBlock(
- parentHash,
- coinbase,
- root,
- common.BigPow(2, 32),
- 0,
- nil)
- block.SetUncles(nil)
- block.SetTransactions(nil)
- block.SetReceipts(nil)
-
- parent := bc.currentBlock
- if parent != nil {
- header := block.Header()
- header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
- header.Number = new(big.Int).Add(parent.Header().Number, common.Big1)
- header.GasLimit = CalcGasLimit(parent)
- }
-
- return block
-}
-
func (bc *ChainManager) Reset() {
bc.mu.Lock()
defer bc.mu.Unlock()
@@ -463,6 +427,19 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
}
+// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
+func (self *ChainManager) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
+ for i := 0; i < n; i++ {
+ block := self.GetBlock(hash)
+ if block == nil {
+ break
+ }
+ blocks = append(blocks, block)
+ hash = block.ParentHash()
+ }
+ return
+}
+
// non blocking version
func (self *ChainManager) getBlockByNumber(num uint64) *types.Block {
key, _ := self.blockDb.Get(append(blockNumPre, big.NewInt(int64(num)).Bytes()...))
@@ -482,19 +459,6 @@ func (self *ChainManager) GetUnclesInChain(block *types.Block, length int) (uncl
return
}
-func (self *ChainManager) GetAncestors(block *types.Block, length int) (blocks []*types.Block) {
- for i := 0; i < length; i++ {
- block = self.GetBlock(block.ParentHash())
- if block == nil {
- break
- }
-
- blocks = append(blocks, block)
- }
-
- return
-}
-
// setTotalDifficulty updates the TD of the chain manager. Note, this function
// assumes that the `mu` mutex is held!
func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
@@ -621,14 +585,12 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
return i, fmt.Errorf("%v: BlockFutureErr, %v > %v", BlockFutureErr, block.Time(), max)
}
- block.SetQueued(true)
self.futureBlocks.Push(block)
stats.queued++
continue
}
if IsParentErr(err) && self.futureBlocks.Has(block.ParentHash()) {
- block.SetQueued(true)
self.futureBlocks.Push(block)
stats.queued++
continue