github.com/dmmcquay/sia@v1.3.1-0.20180712220038-9f8d535311b9/siatest/miner.go (about)

     1  package siatest
     2  
     3  import (
     4  	"bytes"
     5  	"unsafe"
     6  
     7  	"github.com/NebulousLabs/Sia/crypto"
     8  	"github.com/NebulousLabs/Sia/encoding"
     9  	"github.com/NebulousLabs/Sia/types"
    10  	"github.com/NebulousLabs/errors"
    11  )
    12  
    13  // MineBlock makes the underlying node mine a single block and broadcast it.
    14  func (tn *TestNode) MineBlock() error {
    15  	// Get the header
    16  	target, header, err := tn.MinerHeaderGet()
    17  	if err != nil {
    18  		return errors.AddContext(err, "failed to get header for work")
    19  	}
    20  	// Solve the header
    21  	header, err = solveHeader(target, header)
    22  	if err != nil {
    23  		return errors.AddContext(err, "failed to solve header")
    24  	}
    25  	// Submit the header
    26  	if err := tn.MinerHeaderPost(header); err != nil {
    27  		return errors.AddContext(err, "failed to submit header")
    28  	}
    29  	return nil
    30  }
    31  
    32  // solveHeader solves the header by finding a nonce for the target
    33  func solveHeader(target types.Target, bh types.BlockHeader) (types.BlockHeader, error) {
    34  	header := encoding.Marshal(bh)
    35  	var nonce uint64
    36  	for i := 0; i < 256; i++ {
    37  		id := crypto.HashBytes(header)
    38  		if bytes.Compare(target[:], id[:]) >= 0 {
    39  			copy(bh.Nonce[:], header[32:40])
    40  			return bh, nil
    41  		}
    42  		*(*uint64)(unsafe.Pointer(&header[32])) = nonce
    43  		nonce++
    44  	}
    45  	return bh, errors.New("couldn't solve block")
    46  }