在eth/concensus.go中主要是驗證區塊頭,調整挖礦難度的演算法,以及驗證挖到的區塊是否正確等等功能。還有前期準備,計算獎勵等
// VerifySeal implements consensus.Engine, checking whether the given block satisfies// the PoW difficulty requirements.func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error {// If we're running a fake PoW, accept any seal as validif ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake {time.Sleep(ethash.fakeDelay)if ethash.fakeFail == header.Number.Uint64() {return errInvalidPoW}return nil}// If we're running a shared PoW, delegate verification to itif ethash.shared != nil {return ethash.shared.VerifySeal(chain, header)}// Sanity check that the block number is below the lookup table size (60M blocks)number := header.Number.Uint64()if number/epochLength >= uint64(len(cacheSizes)) {// Go < 1.7 cannot calculate new cache/dataset sizes (no fast prime check)return errNonceOutOfRange}// Ensure that we have a valid difficulty for the blockif header.Difficulty.Sign() <= 0 {return errInvalidDifficulty}// Recompute the digest and PoW value and verify against the headercache := ethash.cache(number)size := datasetSize(number)if ethash.config.PowMode == ModeTest {size = 32 * 1024}digest, result := hashimotoLight(size, cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64())if !bytes.Equal(header.MixDigest[:], digest) {return errInvalidMixDigest}target := new(big.Int).Div(maxUint256, header.Difficulty)if new(big.Int).SetBytes(result).Cmp(target) > 0 {return errInvalidPoW}return nil}
在sealer.go中主要是mine和seal兩個函數。 // Seal implements consensus.Engine, attempting to find a nonce that satisfies // the block's difficulty requirements.
mine is the actual proof-of-work miner that searches for a nonce starting from // seed that results in correct final block difficulty.