Skip to content

Commit

Permalink
Merge pull request #212 from iquidus/dev/dag-pregen
Browse files Browse the repository at this point in the history
1099 miner DAG pre-generation fix
  • Loading branch information
iquidus authored Oct 15, 2020
2 parents f34347b + a9f16aa commit 8339c8f
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 7 deletions.
26 changes: 26 additions & 0 deletions consensus/ethash/algorithm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,32 @@ func prepare(dest []uint32, src []byte) {
}
}

// Tests whether calcEpoch returns the correct epoch
func TestCalcEpoch(t *testing.T) {
blockNum := uint64(120000)
want := uint64(blockNum / epochLengthDefault)
if epoch := calcEpoch(blockNum, epochLengthDefault); epoch != want {
t.Errorf("epoch: epoch mismatch: have %d, want %d", epoch, want)
}
want = uint64(blockNum / epochLengthECIP1099)
if epoch := calcEpoch(blockNum, epochLengthECIP1099); epoch != want {
t.Errorf("epoch: epoch mismatch: have %d, want %d", epoch, want)
}
}

// Tests whether calcEpochLength returns the correct epoch length
func TestCalcEpochLength(t *testing.T) {
ecip1099FBlock := uint64(2520000) // mordor
epochLength := calcEpochLength(uint64(ecip1099FBlock-1), &ecip1099FBlock)
if epochLength != epochLengthDefault {
t.Errorf("epoch: length mismatch: have %d, want %d", epochLength, epochLengthDefault)
}
epochLength = calcEpochLength(ecip1099FBlock, &ecip1099FBlock)
if epochLength != epochLengthECIP1099 {
t.Errorf("epoch: length mismatch: have %d, want %d", epochLength, epochLengthECIP1099)
}
}

// Tests whether the dataset size calculator works correctly by cross checking the
// hard coded lookup table with the value generated by it.
func TestSizeCalculations(t *testing.T) {
Expand Down
26 changes: 19 additions & 7 deletions consensus/ethash/ethash.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func newlru(what string, maxItems int, new func(epoch uint64, epochLength uint64
// get retrieves or creates an item for the given epoch. The first return value is always
// non-nil. The second return value is non-nil if lru thinks that an item will be useful in
// the near future.
func (lru *lru) get(epoch uint64, epochLength uint64) (item, future interface{}) {
func (lru *lru) get(epoch uint64, epochLength uint64, ecip1099FBlock *uint64) (item, future interface{}) {
lru.mu.Lock()
defer lru.mu.Unlock()

Expand All @@ -194,11 +194,23 @@ func (lru *lru) get(epoch uint64, epochLength uint64) (item, future interface{})
}
lru.cache.Add(epoch, item)
}

// Ensure pre-generation handles ecip-1099 changeover correctly
var nextEpoch = epoch + 1
var nextEpochLength = epochLength
if ecip1099FBlock != nil {
nextEpochBlock := nextEpoch * epochLength
if nextEpochBlock == *ecip1099FBlock && epochLength == epochLengthDefault {
nextEpoch = nextEpoch / 2
nextEpochLength = epochLengthECIP1099
}
}

// Update the 'future item' if epoch is larger than previously seen.
if epoch < maxEpoch-1 && lru.future < epoch+1 {
log.Trace("Requiring new future ethash "+lru.what, "epoch", epoch+1)
future = lru.new(epoch+1, epochLength)
lru.future = epoch + 1
if epoch < maxEpoch-1 && lru.future < nextEpoch {
log.Trace("Requiring new future ethash "+lru.what, "epoch", nextEpoch)
future = lru.new(nextEpoch, nextEpochLength)
lru.future = nextEpoch
lru.futureItem = future
}
return item, future
Expand Down Expand Up @@ -561,7 +573,7 @@ func (ethash *Ethash) Close() error {
func (ethash *Ethash) cache(block uint64) *cache {
epochLength := calcEpochLength(block, ethash.config.ECIP1099Block)
epoch := calcEpoch(block, epochLength)
currentI, futureI := ethash.caches.get(epoch, epochLength)
currentI, futureI := ethash.caches.get(epoch, epochLength, ethash.config.ECIP1099Block)
current := currentI.(*cache)

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

// If async is specified, generate everything in a background thread
Expand Down
51 changes: 51 additions & 0 deletions consensus/ethash/ethash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package ethash

import (
"io/ioutil"
"math"
"math/big"
"math/rand"
"os"
Expand All @@ -30,6 +31,56 @@ import (
"github.com/ethereum/go-ethereum/core/types"
)

// Tests caches get sets correct future
func TestCachesGet(t *testing.T) {
ethashA := NewTester(nil, false)
defer ethashA.Close()

ethashB := NewTester(nil, false)
defer ethashB.Close()

ethashC := NewTester(nil, false)
defer ethashC.Close()

var (
epoch uint64 = 83
ecip1099Block uint64 = 2520000
nextEpochDefault uint64 = 84
nextEpochECIP1099 uint64 = 42
maxUint64 uint64 = math.MaxUint64
)
// test without ecip-1099 enabled
currentIA, futureIA := ethashA.caches.get(epoch, epochLengthDefault, &maxUint64)
currentA := currentIA.(*cache)
if currentA.epoch != epoch {
t.Errorf("cache: current epoch mismatch: have %d, want %d", currentA.epoch, epoch)
}
futureA := futureIA.(*cache)
if futureA.epoch != nextEpochDefault {
t.Errorf("cache: future epoch mismatch: have %d, want %d", futureA.epoch, nextEpochDefault)
}
// test activation boundary of ecip-1099
currentIB, futureIB := ethashB.caches.get(epoch, epochLengthDefault, &ecip1099Block)
currentB := currentIB.(*cache)
if currentB.epoch != epoch {
t.Errorf("cache: current epoch mismatch: have %d, want %d", currentB.epoch, epoch)
}
futureB := futureIB.(*cache)
if futureB.epoch != nextEpochECIP1099 {
t.Errorf("cache: future epoch mismatch: have %d, want %d", futureB.epoch, nextEpochECIP1099)
}
// test post ecip-1099 activation
currentIC, futureIC := ethashC.caches.get(nextEpochECIP1099, epochLengthECIP1099, &ecip1099Block)
currentC := currentIC.(*cache)
if currentC.epoch != nextEpochECIP1099 {
t.Errorf("cache: current epoch mismatch: have %d, want %d", currentC.epoch, nextEpochECIP1099)
}
futureC := futureIC.(*cache)
if futureC.epoch != nextEpochECIP1099+1 {
t.Errorf("cache: future epoch mismatch: have %d, want %d", futureC.epoch, nextEpochECIP1099+1)
}
}

// Tests that ethash works correctly in test mode.
func TestTestMode(t *testing.T) {
header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)}
Expand Down

0 comments on commit 8339c8f

Please sign in to comment.