chain_util.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // go-ethereum is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package core
  17. import (
  18. "bytes"
  19. "math/big"
  20. "time"
  21. "github.com/ethereum/go-ethereum/common"
  22. "github.com/ethereum/go-ethereum/core/types"
  23. "github.com/ethereum/go-ethereum/logger"
  24. "github.com/ethereum/go-ethereum/logger/glog"
  25. "github.com/ethereum/go-ethereum/params"
  26. "github.com/ethereum/go-ethereum/rlp"
  27. )
  28. var (
  29. blockHashPre = []byte("block-hash-")
  30. blockNumPre = []byte("block-num-")
  31. )
  32. // CalcDifficulty is the difficulty adjustment algorithm. It returns
  33. // the difficulty that a new block b should have when created at time
  34. // given the parent block's time and difficulty.
  35. func CalcDifficulty(time, parentTime uint64, parentDiff *big.Int) *big.Int {
  36. diff := new(big.Int)
  37. adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
  38. bigTime := new(big.Int)
  39. bigParentTime := new(big.Int)
  40. bigTime.SetUint64(time)
  41. bigParentTime.SetUint64(parentTime)
  42. if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 {
  43. diff.Add(parentDiff, adjust)
  44. } else {
  45. diff.Sub(parentDiff, adjust)
  46. }
  47. if diff.Cmp(params.MinimumDifficulty) < 0 {
  48. return params.MinimumDifficulty
  49. }
  50. return diff
  51. }
  52. // CalcTD computes the total difficulty of block.
  53. func CalcTD(block, parent *types.Block) *big.Int {
  54. if parent == nil {
  55. return block.Difficulty()
  56. }
  57. d := block.Difficulty()
  58. d.Add(d, parent.Td)
  59. return d
  60. }
  61. // CalcGasLimit computes the gas limit of the next block after parent.
  62. // The result may be modified by the caller.
  63. func CalcGasLimit(parent *types.Block) *big.Int {
  64. decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor)
  65. contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3))
  66. contrib = contrib.Div(contrib, big.NewInt(2))
  67. contrib = contrib.Div(contrib, params.GasLimitBoundDivisor)
  68. gl := new(big.Int).Sub(parent.GasLimit(), decay)
  69. gl = gl.Add(gl, contrib)
  70. gl = gl.Add(gl, big.NewInt(1))
  71. gl.Set(common.BigMax(gl, params.MinGasLimit))
  72. if gl.Cmp(params.GenesisGasLimit) < 0 {
  73. gl.Add(parent.GasLimit(), decay)
  74. gl.Set(common.BigMin(gl, params.GenesisGasLimit))
  75. }
  76. return gl
  77. }
  78. // GetBlockByHash returns the block corresponding to the hash or nil if not found
  79. func GetBlockByHash(db common.Database, hash common.Hash) *types.Block {
  80. data, _ := db.Get(append(blockHashPre, hash[:]...))
  81. if len(data) == 0 {
  82. return nil
  83. }
  84. var block types.StorageBlock
  85. if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
  86. glog.V(logger.Error).Infof("invalid block RLP for hash %x: %v", hash, err)
  87. return nil
  88. }
  89. return (*types.Block)(&block)
  90. }
  91. // GetBlockByHash returns the canonical block by number or nil if not found
  92. func GetBlockByNumber(db common.Database, number uint64) *types.Block {
  93. key, _ := db.Get(append(blockNumPre, big.NewInt(int64(number)).Bytes()...))
  94. if len(key) == 0 {
  95. return nil
  96. }
  97. return GetBlockByHash(db, common.BytesToHash(key))
  98. }
  99. // WriteHead force writes the current head
  100. func WriteHead(db common.Database, block *types.Block) error {
  101. key := append(blockNumPre, block.Number().Bytes()...)
  102. err := db.Put(key, block.Hash().Bytes())
  103. if err != nil {
  104. return err
  105. }
  106. err = db.Put([]byte("LastBlock"), block.Hash().Bytes())
  107. if err != nil {
  108. return err
  109. }
  110. return nil
  111. }
  112. // WriteBlock writes a block to the database
  113. func WriteBlock(db common.Database, block *types.Block) error {
  114. tstart := time.Now()
  115. enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block))
  116. key := append(blockHashPre, block.Hash().Bytes()...)
  117. err := db.Put(key, enc)
  118. if err != nil {
  119. glog.Fatal("db write fail:", err)
  120. return err
  121. }
  122. if glog.V(logger.Debug) {
  123. glog.Infof("wrote block #%v %s. Took %v\n", block.Number(), common.PP(block.Hash().Bytes()), time.Since(tstart))
  124. }
  125. return nil
  126. }