Merge pull request #1588 from obscuren/diff-bomb

core, miner: added difficulty bomb
This commit is contained in:
Jeffrey Wilcke 2015-08-05 04:26:57 -07:00
commit f12e0161ca
6 changed files with 196 additions and 7 deletions

View File

@ -386,7 +386,7 @@ func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, check
return BlockEqualTSErr
}
expd := CalcDifficulty(block.Time, parent.Time(), parent.Difficulty())
expd := CalcDifficulty(block.Time, parent.Time(), parent.Number(), parent.Difficulty())
if expd.Cmp(block.Difficulty) != 0 {
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
}

View File

@ -171,7 +171,7 @@ func makeHeader(parent *types.Block, state *state.StateDB) *types.Header {
Root: state.Root(),
ParentHash: parent.Hash(),
Coinbase: parent.Coinbase(),
Difficulty: CalcDifficulty(time, parent.Time(), parent.Difficulty()),
Difficulty: CalcDifficulty(time, parent.Time(), parent.Number(), parent.Difficulty()),
GasLimit: CalcGasLimit(parent),
GasUsed: new(big.Int),
Number: new(big.Int).Add(parent.Number(), common.Big1),

View File

@ -32,12 +32,13 @@ import (
var (
blockHashPre = []byte("block-hash-")
blockNumPre = []byte("block-num-")
expDiffPeriod = big.NewInt(100000)
)
// 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, parentTime uint64, parentDiff *big.Int) *big.Int {
func CalcDifficulty(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
diff := new(big.Int)
adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
bigTime := new(big.Int)
@ -52,8 +53,19 @@ func CalcDifficulty(time, parentTime uint64, parentDiff *big.Int) *big.Int {
diff.Sub(parentDiff, adjust)
}
if diff.Cmp(params.MinimumDifficulty) < 0 {
return params.MinimumDifficulty
diff = params.MinimumDifficulty
}
periodCount := new(big.Int).Add(parentNumber, common.Big1)
periodCount.Div(periodCount, expDiffPeriod)
if periodCount.Cmp(common.Big1) > 0 {
// diff = diff + 2^(periodCount - 2)
expDiff := periodCount.Sub(periodCount, common.Big2)
expDiff.Exp(common.Big2, expDiff, nil)
diff.Add(diff, expDiff)
diff = common.BigMax(diff, params.MinimumDifficulty)
}
return diff
}

77
core/chain_util_test.go Normal file
View File

@ -0,0 +1,77 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package core
import (
"encoding/json"
"math/big"
"os"
"testing"
"github.com/ethereum/go-ethereum/common"
)
type diffTest struct {
ParentTimestamp uint64
ParentDifficulty *big.Int
CurrentTimestamp uint64
CurrentBlocknumber *big.Int
CurrentDifficulty *big.Int
}
func (d *diffTest) UnmarshalJSON(b []byte) (err error) {
var ext struct {
ParentTimestamp string
ParentDifficulty string
CurrentTimestamp string
CurrentBlocknumber string
CurrentDifficulty string
}
if err := json.Unmarshal(b, &ext); err != nil {
return err
}
d.ParentTimestamp = common.String2Big(ext.ParentTimestamp).Uint64()
d.ParentDifficulty = common.String2Big(ext.ParentDifficulty)
d.CurrentTimestamp = common.String2Big(ext.CurrentTimestamp).Uint64()
d.CurrentBlocknumber = common.String2Big(ext.CurrentBlocknumber)
d.CurrentDifficulty = common.String2Big(ext.CurrentDifficulty)
return nil
}
func TestDifficulty(t *testing.T) {
file, err := os.Open("../tests/files/BasicTests/difficulty.json")
if err != nil {
t.Fatal(err)
}
defer file.Close()
tests := make(map[string]diffTest)
err = json.NewDecoder(file).Decode(&tests)
if err != nil {
t.Fatal(err)
}
for name, test := range tests {
number := new(big.Int).Sub(test.CurrentBlocknumber, big.NewInt(1))
diff := CalcDifficulty(test.CurrentTimestamp, test.ParentTimestamp, number, test.ParentDifficulty)
if diff.Cmp(test.CurrentDifficulty) != 0 {
t.Error(name, "failed. Expected", test.CurrentDifficulty, "and calculated", diff)
}
}
}

View File

@ -445,7 +445,7 @@ func (self *worker) commitNewWork() {
header := &types.Header{
ParentHash: parent.Hash(),
Number: num.Add(num, common.Big1),
Difficulty: core.CalcDifficulty(uint64(tstamp), parent.Time(), parent.Difficulty()),
Difficulty: core.CalcDifficulty(uint64(tstamp), parent.Time(), parent.Number(), parent.Difficulty()),
GasLimit: core.CalcGasLimit(parent),
GasUsed: new(big.Int),
Coinbase: self.coinbase,

View File

@ -0,0 +1,100 @@
{
"preExpDiffIncrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "42",
"currentDifficulty" : "1000488"
},
"preExpDiffDecrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "42",
"currentDifficulty" : "999512"
},
"ExpDiffAtBlock200000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "200000",
"currentDifficulty" : "1000489"
},
"ExpDiffAtBlock200000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "200000",
"currentDifficulty" : "999513"
},
"ExpDiffPostBlock200000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "200001",
"currentDifficulty" : "1000489"
},
"ExpDiffPostBlock200000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "200001",
"currentDifficulty" : "999513"
},
"ExpDiffPreBlock300000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "299999",
"currentDifficulty" : "1000489"
},
"ExpDiffPreBlock300000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "299999",
"currentDifficulty" : "999513"
},
"ExpDiffAtBlock300000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "300000",
"currentDifficulty" : "1000490"
},
"ExpDiffAtBlock300000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "300000",
"currentDifficulty" : "999514"
},
"ExpDiffPostBlock300000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "300001",
"currentDifficulty" : "1000490"
},
"ExpDiffPostBlock300000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "300001",
"currentDifficulty" : "999514"
},
"ExpDiffInAYearIncrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "2302400",
"currentDifficulty" : "3097640"
},
"ExpDiffInAYearDecrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "2302400",
"currentDifficulty" : "3096664"
}
}