Skip to content

Commit 71d32f5

Browse files
committed
core, miner: added difficulty bomb
1 parent 56219a5 commit 71d32f5

File tree

6 files changed

+196
-7
lines changed

6 files changed

+196
-7
lines changed

core/block_processor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, check
386386
return BlockEqualTSErr
387387
}
388388

389-
expd := CalcDifficulty(block.Time, parent.Time(), parent.Difficulty())
389+
expd := CalcDifficulty(block.Time, parent.Time(), parent.Number(), parent.Difficulty())
390390
if expd.Cmp(block.Difficulty) != 0 {
391391
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
392392
}

core/chain_makers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ func makeHeader(parent *types.Block, state *state.StateDB) *types.Header {
171171
Root: state.Root(),
172172
ParentHash: parent.Hash(),
173173
Coinbase: parent.Coinbase(),
174-
Difficulty: CalcDifficulty(time, parent.Time(), parent.Difficulty()),
174+
Difficulty: CalcDifficulty(time, parent.Time(), parent.Number(), parent.Difficulty()),
175175
GasLimit: CalcGasLimit(parent),
176176
GasUsed: new(big.Int),
177177
Number: new(big.Int).Add(parent.Number(), common.Big1),

core/chain_util.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ import (
3030
)
3131

3232
var (
33-
blockHashPre = []byte("block-hash-")
34-
blockNumPre = []byte("block-num-")
33+
blockHashPre = []byte("block-hash-")
34+
blockNumPre = []byte("block-num-")
35+
expDiffPeriod = big.NewInt(100000)
3536
)
3637

3738
// CalcDifficulty is the difficulty adjustment algorithm. It returns
3839
// the difficulty that a new block b should have when created at time
3940
// given the parent block's time and difficulty.
40-
func CalcDifficulty(time, parentTime uint64, parentDiff *big.Int) *big.Int {
41+
func CalcDifficulty(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
4142
diff := new(big.Int)
4243
adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
4344
bigTime := new(big.Int)
@@ -52,8 +53,19 @@ func CalcDifficulty(time, parentTime uint64, parentDiff *big.Int) *big.Int {
5253
diff.Sub(parentDiff, adjust)
5354
}
5455
if diff.Cmp(params.MinimumDifficulty) < 0 {
55-
return params.MinimumDifficulty
56+
diff = params.MinimumDifficulty
5657
}
58+
59+
periodCount := new(big.Int).Add(parentNumber, common.Big1)
60+
periodCount.Div(periodCount, expDiffPeriod)
61+
if periodCount.Cmp(common.Big1) > 0 {
62+
// diff = diff + 2^(periodCount - 2)
63+
expDiff := periodCount.Sub(periodCount, common.Big2)
64+
expDiff.Exp(common.Big2, expDiff, nil)
65+
diff.Add(diff, expDiff)
66+
diff = common.BigMax(diff, params.MinimumDifficulty)
67+
}
68+
5769
return diff
5870
}
5971

core/chain_util_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright 2015 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library 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+
17+
package core
18+
19+
import (
20+
"encoding/json"
21+
"math/big"
22+
"os"
23+
"testing"
24+
25+
"github.com/ethereum/go-ethereum/common"
26+
)
27+
28+
type diffTest struct {
29+
ParentTimestamp uint64
30+
ParentDifficulty *big.Int
31+
CurrentTimestamp uint64
32+
CurrentBlocknumber *big.Int
33+
CurrentDifficulty *big.Int
34+
}
35+
36+
func (d *diffTest) UnmarshalJSON(b []byte) (err error) {
37+
var ext struct {
38+
ParentTimestamp string
39+
ParentDifficulty string
40+
CurrentTimestamp string
41+
CurrentBlocknumber string
42+
CurrentDifficulty string
43+
}
44+
if err := json.Unmarshal(b, &ext); err != nil {
45+
return err
46+
}
47+
48+
d.ParentTimestamp = common.String2Big(ext.ParentTimestamp).Uint64()
49+
d.ParentDifficulty = common.String2Big(ext.ParentDifficulty)
50+
d.CurrentTimestamp = common.String2Big(ext.CurrentTimestamp).Uint64()
51+
d.CurrentBlocknumber = common.String2Big(ext.CurrentBlocknumber)
52+
d.CurrentDifficulty = common.String2Big(ext.CurrentDifficulty)
53+
54+
return nil
55+
}
56+
57+
func TestDifficulty(t *testing.T) {
58+
file, err := os.Open("../tests/files/BasicTests/difficulty.json")
59+
if err != nil {
60+
t.Fatal(err)
61+
}
62+
defer file.Close()
63+
64+
tests := make(map[string]diffTest)
65+
err = json.NewDecoder(file).Decode(&tests)
66+
if err != nil {
67+
t.Fatal(err)
68+
}
69+
70+
for name, test := range tests {
71+
number := new(big.Int).Sub(test.CurrentBlocknumber, big.NewInt(1))
72+
diff := CalcDifficulty(test.CurrentTimestamp, test.ParentTimestamp, number, test.ParentDifficulty)
73+
if diff.Cmp(test.CurrentDifficulty) != 0 {
74+
t.Error(name, "failed. Expected", test.CurrentDifficulty, "and calculated", diff)
75+
}
76+
}
77+
}

miner/worker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ func (self *worker) commitNewWork() {
444444
header := &types.Header{
445445
ParentHash: parent.Hash(),
446446
Number: num.Add(num, common.Big1),
447-
Difficulty: core.CalcDifficulty(uint64(tstamp), parent.Time(), parent.Difficulty()),
447+
Difficulty: core.CalcDifficulty(uint64(tstamp), parent.Time(), parent.Number(), parent.Difficulty()),
448448
GasLimit: core.CalcGasLimit(parent),
449449
GasUsed: new(big.Int),
450450
Coinbase: self.coinbase,
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
{
2+
"preExpDiffIncrease" : {
3+
"parentTimestamp" : "42",
4+
"parentDifficulty" : "1000000",
5+
"currentTimestamp" : "43",
6+
"currentBlockNumber" : "42",
7+
"currentDifficulty" : "1000488"
8+
},
9+
"preExpDiffDecrease" : {
10+
"parentTimestamp" : "42",
11+
"parentDifficulty" : "1000000",
12+
"currentTimestamp" : "60",
13+
"currentBlockNumber" : "42",
14+
"currentDifficulty" : "999512"
15+
},
16+
"ExpDiffAtBlock200000Increase" : {
17+
"parentTimestamp" : "42",
18+
"parentDifficulty" : "1000000",
19+
"currentTimestamp" : "43",
20+
"currentBlockNumber" : "200000",
21+
"currentDifficulty" : "1000489"
22+
},
23+
"ExpDiffAtBlock200000Decrease" : {
24+
"parentTimestamp" : "42",
25+
"parentDifficulty" : "1000000",
26+
"currentTimestamp" : "60",
27+
"currentBlockNumber" : "200000",
28+
"currentDifficulty" : "999513"
29+
},
30+
"ExpDiffPostBlock200000Increase" : {
31+
"parentTimestamp" : "42",
32+
"parentDifficulty" : "1000000",
33+
"currentTimestamp" : "43",
34+
"currentBlockNumber" : "200001",
35+
"currentDifficulty" : "1000489"
36+
},
37+
"ExpDiffPostBlock200000Decrease" : {
38+
"parentTimestamp" : "42",
39+
"parentDifficulty" : "1000000",
40+
"currentTimestamp" : "60",
41+
"currentBlockNumber" : "200001",
42+
"currentDifficulty" : "999513"
43+
},
44+
"ExpDiffPreBlock300000Increase" : {
45+
"parentTimestamp" : "42",
46+
"parentDifficulty" : "1000000",
47+
"currentTimestamp" : "43",
48+
"currentBlockNumber" : "299999",
49+
"currentDifficulty" : "1000489"
50+
},
51+
"ExpDiffPreBlock300000Decrease" : {
52+
"parentTimestamp" : "42",
53+
"parentDifficulty" : "1000000",
54+
"currentTimestamp" : "60",
55+
"currentBlockNumber" : "299999",
56+
"currentDifficulty" : "999513"
57+
},
58+
"ExpDiffAtBlock300000Increase" : {
59+
"parentTimestamp" : "42",
60+
"parentDifficulty" : "1000000",
61+
"currentTimestamp" : "43",
62+
"currentBlockNumber" : "300000",
63+
"currentDifficulty" : "1000490"
64+
},
65+
"ExpDiffAtBlock300000Decrease" : {
66+
"parentTimestamp" : "42",
67+
"parentDifficulty" : "1000000",
68+
"currentTimestamp" : "60",
69+
"currentBlockNumber" : "300000",
70+
"currentDifficulty" : "999514"
71+
},
72+
"ExpDiffPostBlock300000Increase" : {
73+
"parentTimestamp" : "42",
74+
"parentDifficulty" : "1000000",
75+
"currentTimestamp" : "43",
76+
"currentBlockNumber" : "300001",
77+
"currentDifficulty" : "1000490"
78+
},
79+
"ExpDiffPostBlock300000Decrease" : {
80+
"parentTimestamp" : "42",
81+
"parentDifficulty" : "1000000",
82+
"currentTimestamp" : "60",
83+
"currentBlockNumber" : "300001",
84+
"currentDifficulty" : "999514"
85+
},
86+
"ExpDiffInAYearIncrease" : {
87+
"parentTimestamp" : "42",
88+
"parentDifficulty" : "1000000",
89+
"currentTimestamp" : "43",
90+
"currentBlockNumber" : "2302400",
91+
"currentDifficulty" : "3097640"
92+
},
93+
"ExpDiffInAYearDecrease" : {
94+
"parentTimestamp" : "42",
95+
"parentDifficulty" : "1000000",
96+
"currentTimestamp" : "60",
97+
"currentBlockNumber" : "2302400",
98+
"currentDifficulty" : "3096664"
99+
}
100+
}

0 commit comments

Comments
 (0)