Ejemplo n.º 1
0
func (b Block) Verify() bool {
	databytes, err := hex.DecodeString(b.header[0:360])
	if err != nil {
		return false
	}
	hash := chainhash.HashFuncH(databytes)
	hashNum := blockchain.ShaHashToBig(&hash)
	return hashNum.Cmp(b.difficulty) <= 0
}
Ejemplo n.º 2
0
/* convert target come from getwork to big integer
   "ffffffffffffffffffffffffffffffffffffffffffffffffffffff3f00000000"
*/
func TargetStrToDiff(targetHex string) *big.Int {
	hashbytes, err := hex.DecodeString(targetHex)
	if err != nil {
		return big.NewInt(0)
	}
	hash, err := chainhash.NewHash(hashbytes)
	if err != nil {
		return big.NewInt(0)
	}
	targetdiff := blockchain.ShaHashToBig(hash)
	if targetdiff.Cmp(big.NewInt(0)) != 0 {
		targetdiff.Div(PowLimit, targetdiff)
	}
	return targetdiff
}
Ejemplo n.º 3
0
// solveBlock attempts to find some combination of a nonce, extra nonce, and
// current timestamp which makes the passed block hash to a value less than the
// target difficulty.  The timestamp is updated periodically and the passed
// block is modified with all tweaks during this process.  This means that
// when the function returns true, the block is ready for submission.
//
// This function will return early with false when conditions that trigger a
// stale block such as a new block showing up or periodically when there are
// new transactions and enough time has elapsed without finding a solution.
func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, ticker *time.Ticker,
	quit chan struct{}) bool {

	blockHeight := int64(msgBlock.Header.Height)

	// Choose a random extra nonce offset for this block template and
	// worker.
	enOffset, err := wire.RandomUint64()
	if err != nil {
		minrLog.Errorf("Unexpected error while generating random "+
			"extra nonce offset: %v", err)
		enOffset = 0
	}

	// Create a couple of convenience variables.
	header := &msgBlock.Header
	targetDifficulty := blockchain.CompactToBig(header.Bits)

	// Initial state.
	lastGenerated := time.Now()
	lastTxUpdate := m.server.txMemPool.LastUpdated()
	hashesCompleted := uint64(0)

	// Note that the entire extra nonce range is iterated and the offset is
	// added relying on the fact that overflow will wrap around 0 as
	// provided by the Go spec.
	for extraNonce := uint64(0); extraNonce < maxExtraNonce; extraNonce++ {
		// Get the old nonce values.
		ens := getCoinbaseExtranonces(msgBlock)
		ens[2] = extraNonce + enOffset

		// Update the extra nonce in the block template with the
		// new value by regenerating the coinbase script and
		// setting the merkle root to the new value.  The
		UpdateExtraNonce(msgBlock, blockHeight, ens)

		// Search through the entire nonce range for a solution while
		// periodically checking for early quit and stale block
		// conditions along with updates to the speed monitor.
		for i := uint32(0); i <= maxNonce; i++ {
			select {
			case <-quit:
				return false

			case <-ticker.C:
				m.updateHashes <- hashesCompleted
				hashesCompleted = 0

				// The current block is stale if the memory pool
				// has been updated since the block template was
				// generated and it has been at least 3 seconds,
				// or if it's been one minute.
				if (lastTxUpdate != m.server.txMemPool.LastUpdated() &&
					time.Now().After(lastGenerated.Add(3*time.Second))) ||
					time.Now().After(lastGenerated.Add(60*time.Second)) {
					return false
				}

				UpdateBlockTime(msgBlock, m.server.blockManager)

			default:
				// Non-blocking select to fall through
			}

			// Update the nonce and hash the block header.
			header.Nonce = i
			hash := header.BlockSha()
			hashesCompleted += 1

			// The block is solved when the new block hash is less
			// than the target difficulty.  Yay!
			if blockchain.ShaHashToBig(&hash).Cmp(targetDifficulty) <= 0 {
				m.updateHashes <- hashesCompleted
				return true
			}
		}
	}

	return false
}