chain_util.go 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package core
  2. import (
  3. "bytes"
  4. "math/big"
  5. "github.com/ethereum/go-ethereum/common"
  6. "github.com/ethereum/go-ethereum/core/types"
  7. "github.com/ethereum/go-ethereum/logger"
  8. "github.com/ethereum/go-ethereum/logger/glog"
  9. "github.com/ethereum/go-ethereum/params"
  10. "github.com/ethereum/go-ethereum/rlp"
  11. )
  12. // CalcDifficulty is the difficulty adjustment algorithm. It returns
  13. // the difficulty that a new block b should have when created at time
  14. // given the parent block's time and difficulty.
  15. func CalcDifficulty(time int64, parentTime int64, parentDiff *big.Int) *big.Int {
  16. diff := new(big.Int)
  17. adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
  18. if big.NewInt(time-parentTime).Cmp(params.DurationLimit) < 0 {
  19. diff.Add(parentDiff, adjust)
  20. } else {
  21. diff.Sub(parentDiff, adjust)
  22. }
  23. if diff.Cmp(params.MinimumDifficulty) < 0 {
  24. return params.MinimumDifficulty
  25. }
  26. return diff
  27. }
  28. // CalcTD computes the total difficulty of block.
  29. func CalcTD(block, parent *types.Block) *big.Int {
  30. if parent == nil {
  31. return block.Difficulty()
  32. }
  33. d := block.Difficulty()
  34. d.Add(d, parent.Td)
  35. return d
  36. }
  37. // CalcGasLimit computes the gas limit of the next block after parent.
  38. // The result may be modified by the caller.
  39. func CalcGasLimit(parent *types.Block) *big.Int {
  40. decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor)
  41. contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3))
  42. contrib = contrib.Div(contrib, big.NewInt(2))
  43. contrib = contrib.Div(contrib, params.GasLimitBoundDivisor)
  44. gl := new(big.Int).Sub(parent.GasLimit(), decay)
  45. gl = gl.Add(gl, contrib)
  46. gl = gl.Add(gl, big.NewInt(1))
  47. gl.Set(common.BigMax(gl, params.MinGasLimit))
  48. if gl.Cmp(params.GenesisGasLimit) < 0 {
  49. gl.Add(parent.GasLimit(), decay)
  50. gl.Set(common.BigMin(gl, params.GenesisGasLimit))
  51. }
  52. return gl
  53. }
  54. // GetBlockByHash returns the block corresponding to the hash or nil if not found
  55. func GetBlockByHash(db common.Database, hash common.Hash) *types.Block {
  56. data, _ := db.Get(append(blockHashPre, hash[:]...))
  57. if len(data) == 0 {
  58. return nil
  59. }
  60. var block types.StorageBlock
  61. if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
  62. glog.V(logger.Error).Infof("invalid block RLP for hash %x: %v", hash, err)
  63. return nil
  64. }
  65. return (*types.Block)(&block)
  66. }
  67. // GetBlockByHash returns the canonical block by number or nil if not found
  68. func GetBlockByNumber(db common.Database, number uint64) *types.Block {
  69. key, _ := db.Get(append(blockNumPre, big.NewInt(int64(number)).Bytes()...))
  70. if len(key) == 0 {
  71. return nil
  72. }
  73. return GetBlockByHash(db, common.BytesToHash(key))
  74. }
  75. // WriteHead force writes the current head
  76. func WriteHead(db common.Database, block *types.Block) error {
  77. key := append(blockNumPre, block.Number().Bytes()...)
  78. err := db.Put(key, block.Hash().Bytes())
  79. if err != nil {
  80. return err
  81. }
  82. err = db.Put([]byte("LastBlock"), block.Hash().Bytes())
  83. if err != nil {
  84. return err
  85. }
  86. return nil
  87. }