// solveBlock attempts to find a nonce which makes the passed block header hash // to a value less than the target difficulty. When a successful solution is // found true is returned and the nonce field of the passed header is updated // with the solution. False is returned if no solution exists. func solveBlock(header *wire.BlockHeader, targetDifficulty *big.Int) bool { // sbResult is used by the solver goroutines to send results. type sbResult struct { found bool nonce uint32 } // solver accepts a block header and a nonce range to test. It is // intended to be run as a goroutine. quit := make(chan bool) results := make(chan sbResult) solver := func(hdr wire.BlockHeader, startNonce, stopNonce uint32) { // We need to modify the nonce field of the header, so make sure // we work with a copy of the original header. for i := startNonce; i >= startNonce && i <= stopNonce; i++ { select { case <-quit: return default: hdr.Nonce = i hash := hdr.BlockHash() if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 { results <- sbResult{true, i} return } } } results <- sbResult{false, 0} } startNonce := uint32(0) stopNonce := uint32(math.MaxUint32) numCores := uint32(runtime.NumCPU()) noncesPerCore := (stopNonce - startNonce) / numCores for i := uint32(0); i < numCores; i++ { rangeStart := startNonce + (noncesPerCore * i) rangeStop := startNonce + (noncesPerCore * (i + 1)) - 1 if i == numCores-1 { rangeStop = stopNonce } go solver(*header, rangeStart, rangeStop) } for i := uint32(0); i < numCores; i++ { result := <-results if result.found { close(quit) header.Nonce = result.nonce return true } } return false }