aboutsummaryrefslogtreecommitdiffstats
path: root/consensus/ethash/sealer.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@users.noreply.github.com>2018-01-23 18:05:30 +0800
committerPéter Szilágyi <peterke@gmail.com>2018-01-23 18:05:30 +0800
commit924065e19d08cc7e6af0b3a5b5b1ef3785b79bd4 (patch)
tree9aefabb6b4c375971570555486ce5b172660661d /consensus/ethash/sealer.go
parent5d4267911a7791bfa60f275a97347372fbf0ce99 (diff)
downloaddexon-924065e19d08cc7e6af0b3a5b5b1ef3785b79bd4.tar.gz
dexon-924065e19d08cc7e6af0b3a5b5b1ef3785b79bd4.tar.zst
dexon-924065e19d08cc7e6af0b3a5b5b1ef3785b79bd4.zip
consensus/ethash: improve cache/dataset handling (#15864)
* consensus/ethash: add maxEpoch constant * consensus/ethash: improve cache/dataset handling There are two fixes in this commit: Unmap the memory through a finalizer like the libethash wrapper did. The release logic was incorrect and freed the memory while it was being used, leading to crashes like in #14495 or #14943. Track caches and datasets using simplelru instead of reinventing LRU logic. This should make it easier to see whether it's correct. * consensus/ethash: restore 'future item' logic in lru * consensus/ethash: use mmap even in test mode This makes it possible to shorten the time taken for TestCacheFileEvict. * consensus/ethash: shuffle func calc*Size comments around * consensus/ethash: ensure future cache/dataset is in the lru cache * consensus/ethash: add issue link to the new test * consensus/ethash: fix vet * consensus/ethash: fix test * consensus: tiny issue + nitpick fixes
Diffstat (limited to 'consensus/ethash/sealer.go')
-rw-r--r--consensus/ethash/sealer.go17
1 files changed, 10 insertions, 7 deletions
diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go
index c2447e473..b5e742d8b 100644
--- a/consensus/ethash/sealer.go
+++ b/consensus/ethash/sealer.go
@@ -97,10 +97,9 @@ func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, stop
func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan struct{}, found chan *types.Block) {
// Extract some data from the header
var (
- header = block.Header()
- hash = header.HashNoNonce().Bytes()
- target = new(big.Int).Div(maxUint256, header.Difficulty)
-
+ header = block.Header()
+ hash = header.HashNoNonce().Bytes()
+ target = new(big.Int).Div(maxUint256, header.Difficulty)
number = header.Number.Uint64()
dataset = ethash.dataset(number)
)
@@ -111,13 +110,14 @@ func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan s
)
logger := log.New("miner", id)
logger.Trace("Started ethash search for new nonces", "seed", seed)
+search:
for {
select {
case <-abort:
// Mining terminated, update stats and abort
logger.Trace("Ethash nonce search aborted", "attempts", nonce-seed)
ethash.hashrate.Mark(attempts)
- return
+ break search
default:
// We don't have to update hash rate on every nonce, so update after after 2^X nonces
@@ -127,7 +127,7 @@ func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan s
attempts = 0
}
// Compute the PoW value of this nonce
- digest, result := hashimotoFull(dataset, hash, nonce)
+ digest, result := hashimotoFull(dataset.dataset, hash, nonce)
if new(big.Int).SetBytes(result).Cmp(target) <= 0 {
// Correct nonce found, create a new header with it
header = types.CopyHeader(header)
@@ -141,9 +141,12 @@ func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan s
case <-abort:
logger.Trace("Ethash nonce found but discarded", "attempts", nonce-seed, "nonce", nonce)
}
- return
+ break search
}
nonce++
}
}
+ // Datasets are unmapped in a finalizer. Ensure that the dataset stays live
+ // during sealing so it's not unmapped while being read.
+ runtime.KeepAlive(dataset)
}