diff options
author | Jeffrey Wilcke <geffobscura@gmail.com> | 2015-07-01 22:15:02 +0800 |
---|---|---|
committer | Jeffrey Wilcke <geffobscura@gmail.com> | 2015-07-01 22:34:35 +0800 |
commit | 70d5d791cc695cff3b3448a1b4b47816a8bbd83f (patch) | |
tree | 3b21c721577d80e93d78a437c2dda908790ea977 /core/chain_util.go | |
parent | bb418a43c1b9ebf9a32006652b405f8e1cb3acd2 (diff) | |
download | go-tangerine-70d5d791cc695cff3b3448a1b4b47816a8bbd83f.tar.gz go-tangerine-70d5d791cc695cff3b3448a1b4b47816a8bbd83f.tar.zst go-tangerine-70d5d791cc695cff3b3448a1b4b47816a8bbd83f.zip |
core, cmd/geth: improved recover functionality
`geth recover` now accepts both hashes and numbers using "#" and no
longer requires the ethereum instance.
Diffstat (limited to 'core/chain_util.go')
-rw-r--r-- | core/chain_util.go | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/core/chain_util.go b/core/chain_util.go new file mode 100644 index 000000000..8051cc47a --- /dev/null +++ b/core/chain_util.go @@ -0,0 +1,98 @@ +package core + +import ( + "bytes" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// 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(parentDiff, params.DifficultyBoundDivisor) + if big.NewInt(time-parentTime).Cmp(params.DurationLimit) < 0 { + diff.Add(parentDiff, adjust) + } else { + 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() + } + d := block.Difficulty() + d.Add(d, parent.Td) + return d +} + +// 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)) + contrib = contrib.Div(contrib, big.NewInt(2)) + contrib = contrib.Div(contrib, params.GasLimitBoundDivisor) + + gl := new(big.Int).Sub(parent.GasLimit(), decay) + gl = gl.Add(gl, contrib) + gl = gl.Add(gl, big.NewInt(1)) + gl.Set(common.BigMax(gl, params.MinGasLimit)) + + if gl.Cmp(params.GenesisGasLimit) < 0 { + gl.Add(parent.GasLimit(), decay) + gl.Set(common.BigMin(gl, params.GenesisGasLimit)) + } + return gl +} + +// GetBlockByHash returns the block corresponding to the hash or nil if not found +func GetBlockByHash(db common.Database, hash common.Hash) *types.Block { + data, _ := db.Get(append(blockHashPre, hash[:]...)) + if len(data) == 0 { + return nil + } + var block types.StorageBlock + if err := rlp.Decode(bytes.NewReader(data), &block); err != nil { + glog.V(logger.Error).Infof("invalid block RLP for hash %x: %v", hash, err) + return nil + } + return (*types.Block)(&block) +} + +// GetBlockByHash returns the canonical block by number or nil if not found +func GetBlockByNumber(db common.Database, number uint64) *types.Block { + key, _ := db.Get(append(blockNumPre, big.NewInt(int64(number)).Bytes()...)) + if len(key) == 0 { + return nil + } + + return GetBlockByHash(db, common.BytesToHash(key)) +} + +// WriteHead force writes the current head +func WriteHead(db common.Database, block *types.Block) error { + key := append(blockNumPre, block.Number().Bytes()...) + err := db.Put(key, block.Hash().Bytes()) + if err != nil { + return err + } + err = db.Put([]byte("LastBlock"), block.Hash().Bytes()) + if err != nil { + return err + } + return nil +} |