diff options
author | Felix Lange <fjl@users.noreply.github.com> | 2018-01-23 18:05:30 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2018-01-23 18:05:30 +0800 |
commit | 924065e19d08cc7e6af0b3a5b5b1ef3785b79bd4 (patch) | |
tree | 9aefabb6b4c375971570555486ce5b172660661d /consensus/ethash/sealer.go | |
parent | 5d4267911a7791bfa60f275a97347372fbf0ce99 (diff) | |
download | dexon-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.go | 17 |
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) } |