Skip to content

Commit 8339c8f

Browse files
authored
Merge pull request ethereum#212 from iquidus/dev/dag-pregen
1099 miner DAG pre-generation fix
2 parents f34347b + a9f16aa commit 8339c8f

File tree

3 files changed

+96
-7
lines changed

3 files changed

+96
-7
lines changed

consensus/ethash/algorithm_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,32 @@ func prepare(dest []uint32, src []byte) {
4040
}
4141
}
4242

43+
// Tests whether calcEpoch returns the correct epoch
44+
func TestCalcEpoch(t *testing.T) {
45+
blockNum := uint64(120000)
46+
want := uint64(blockNum / epochLengthDefault)
47+
if epoch := calcEpoch(blockNum, epochLengthDefault); epoch != want {
48+
t.Errorf("epoch: epoch mismatch: have %d, want %d", epoch, want)
49+
}
50+
want = uint64(blockNum / epochLengthECIP1099)
51+
if epoch := calcEpoch(blockNum, epochLengthECIP1099); epoch != want {
52+
t.Errorf("epoch: epoch mismatch: have %d, want %d", epoch, want)
53+
}
54+
}
55+
56+
// Tests whether calcEpochLength returns the correct epoch length
57+
func TestCalcEpochLength(t *testing.T) {
58+
ecip1099FBlock := uint64(2520000) // mordor
59+
epochLength := calcEpochLength(uint64(ecip1099FBlock-1), &ecip1099FBlock)
60+
if epochLength != epochLengthDefault {
61+
t.Errorf("epoch: length mismatch: have %d, want %d", epochLength, epochLengthDefault)
62+
}
63+
epochLength = calcEpochLength(ecip1099FBlock, &ecip1099FBlock)
64+
if epochLength != epochLengthECIP1099 {
65+
t.Errorf("epoch: length mismatch: have %d, want %d", epochLength, epochLengthECIP1099)
66+
}
67+
}
68+
4369
// Tests whether the dataset size calculator works correctly by cross checking the
4470
// hard coded lookup table with the value generated by it.
4571
func TestSizeCalculations(t *testing.T) {

consensus/ethash/ethash.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func newlru(what string, maxItems int, new func(epoch uint64, epochLength uint64
179179
// get retrieves or creates an item for the given epoch. The first return value is always
180180
// non-nil. The second return value is non-nil if lru thinks that an item will be useful in
181181
// the near future.
182-
func (lru *lru) get(epoch uint64, epochLength uint64) (item, future interface{}) {
182+
func (lru *lru) get(epoch uint64, epochLength uint64, ecip1099FBlock *uint64) (item, future interface{}) {
183183
lru.mu.Lock()
184184
defer lru.mu.Unlock()
185185

@@ -194,11 +194,23 @@ func (lru *lru) get(epoch uint64, epochLength uint64) (item, future interface{})
194194
}
195195
lru.cache.Add(epoch, item)
196196
}
197+
198+
// Ensure pre-generation handles ecip-1099 changeover correctly
199+
var nextEpoch = epoch + 1
200+
var nextEpochLength = epochLength
201+
if ecip1099FBlock != nil {
202+
nextEpochBlock := nextEpoch * epochLength
203+
if nextEpochBlock == *ecip1099FBlock && epochLength == epochLengthDefault {
204+
nextEpoch = nextEpoch / 2
205+
nextEpochLength = epochLengthECIP1099
206+
}
207+
}
208+
197209
// Update the 'future item' if epoch is larger than previously seen.
198-
if epoch < maxEpoch-1 && lru.future < epoch+1 {
199-
log.Trace("Requiring new future ethash "+lru.what, "epoch", epoch+1)
200-
future = lru.new(epoch+1, epochLength)
201-
lru.future = epoch + 1
210+
if epoch < maxEpoch-1 && lru.future < nextEpoch {
211+
log.Trace("Requiring new future ethash "+lru.what, "epoch", nextEpoch)
212+
future = lru.new(nextEpoch, nextEpochLength)
213+
lru.future = nextEpoch
202214
lru.futureItem = future
203215
}
204216
return item, future
@@ -561,7 +573,7 @@ func (ethash *Ethash) Close() error {
561573
func (ethash *Ethash) cache(block uint64) *cache {
562574
epochLength := calcEpochLength(block, ethash.config.ECIP1099Block)
563575
epoch := calcEpoch(block, epochLength)
564-
currentI, futureI := ethash.caches.get(epoch, epochLength)
576+
currentI, futureI := ethash.caches.get(epoch, epochLength, ethash.config.ECIP1099Block)
565577
current := currentI.(*cache)
566578

567579
// Wait for generation finish.
@@ -585,7 +597,7 @@ func (ethash *Ethash) dataset(block uint64, async bool) *dataset {
585597
// Retrieve the requested ethash dataset
586598
epochLength := calcEpochLength(block, ethash.config.ECIP1099Block)
587599
epoch := calcEpoch(block, epochLength)
588-
currentI, futureI := ethash.datasets.get(epoch, epochLength)
600+
currentI, futureI := ethash.datasets.get(epoch, epochLength, ethash.config.ECIP1099Block)
589601
current := currentI.(*dataset)
590602

591603
// If async is specified, generate everything in a background thread

consensus/ethash/ethash_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package ethash
1818

1919
import (
2020
"io/ioutil"
21+
"math"
2122
"math/big"
2223
"math/rand"
2324
"os"
@@ -30,6 +31,56 @@ import (
3031
"github.com/ethereum/go-ethereum/core/types"
3132
)
3233

34+
// Tests caches get sets correct future
35+
func TestCachesGet(t *testing.T) {
36+
ethashA := NewTester(nil, false)
37+
defer ethashA.Close()
38+
39+
ethashB := NewTester(nil, false)
40+
defer ethashB.Close()
41+
42+
ethashC := NewTester(nil, false)
43+
defer ethashC.Close()
44+
45+
var (
46+
epoch uint64 = 83
47+
ecip1099Block uint64 = 2520000
48+
nextEpochDefault uint64 = 84
49+
nextEpochECIP1099 uint64 = 42
50+
maxUint64 uint64 = math.MaxUint64
51+
)
52+
// test without ecip-1099 enabled
53+
currentIA, futureIA := ethashA.caches.get(epoch, epochLengthDefault, &maxUint64)
54+
currentA := currentIA.(*cache)
55+
if currentA.epoch != epoch {
56+
t.Errorf("cache: current epoch mismatch: have %d, want %d", currentA.epoch, epoch)
57+
}
58+
futureA := futureIA.(*cache)
59+
if futureA.epoch != nextEpochDefault {
60+
t.Errorf("cache: future epoch mismatch: have %d, want %d", futureA.epoch, nextEpochDefault)
61+
}
62+
// test activation boundary of ecip-1099
63+
currentIB, futureIB := ethashB.caches.get(epoch, epochLengthDefault, &ecip1099Block)
64+
currentB := currentIB.(*cache)
65+
if currentB.epoch != epoch {
66+
t.Errorf("cache: current epoch mismatch: have %d, want %d", currentB.epoch, epoch)
67+
}
68+
futureB := futureIB.(*cache)
69+
if futureB.epoch != nextEpochECIP1099 {
70+
t.Errorf("cache: future epoch mismatch: have %d, want %d", futureB.epoch, nextEpochECIP1099)
71+
}
72+
// test post ecip-1099 activation
73+
currentIC, futureIC := ethashC.caches.get(nextEpochECIP1099, epochLengthECIP1099, &ecip1099Block)
74+
currentC := currentIC.(*cache)
75+
if currentC.epoch != nextEpochECIP1099 {
76+
t.Errorf("cache: current epoch mismatch: have %d, want %d", currentC.epoch, nextEpochECIP1099)
77+
}
78+
futureC := futureIC.(*cache)
79+
if futureC.epoch != nextEpochECIP1099+1 {
80+
t.Errorf("cache: future epoch mismatch: have %d, want %d", futureC.epoch, nextEpochECIP1099+1)
81+
}
82+
}
83+
3384
// Tests that ethash works correctly in test mode.
3485
func TestTestMode(t *testing.T) {
3586
header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)}

0 commit comments

Comments
 (0)