Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • lucy
  • ivo/renter_proto_lockcheck
  • ivo/subfile_path_tests
  • minor-siac-feemanager-fix
  • debug-extend
  • 4230-follow-up-from-export-siad-running-modules
  • 4025-siac-cobra-tests
  • ivo/default_path
  • rhp3-try-fix-mismatch
  • portals3-debug
  • bad-contracts
  • increase-make-test-time
  • sync
  • upload-download-script
  • siac-worker-detail
  • 4178-follow-up-from-add-hostblockheight-to-the-rpcpricetable
  • 4181-ea-last-used
  • mdm-write-program-support
  • hostdb-rhp3
  • v1.4.13
  • v1.4.12
  • v1.4.11
  • v1.4.10
  • v1.4.9
  • v1.4.9-rc1
  • v1.4.8
  • v1.4.8-rc2
  • v1.4.8-rc1
  • v1.4.7
  • v1.4.5-final-release
  • v1.4.6-final-release
  • v1.4.6
  • v1.4.5
  • v1.4.4
  • v1.4.4-final-release
  • v1.4.3
  • v1.4.3-final-release
  • v1.4.3.0-rc2
  • v1.4.3.0-rc1
40 results

testminer.go

Forked from NebulousLabs / Sia
14871 commits behind, 5 commits ahead of the upstream repository.
  • David Vorick's avatar
    9f721800
    Change the threadgroup model · 9f721800
    David Vorick authored
    The thread group now has support for pausing. The thread group also
    distinctly distinguishes between BeforeStop and AfterStop, which can
    have key implications depending on the function that is being called.
    9f721800
    History
    Change the threadgroup model
    David Vorick authored
    The thread group now has support for pausing. The thread group also
    distinctly distinguishes between BeforeStop and AfterStop, which can
    have key implications depending on the function that is being called.
testminer.go 2.83 KiB
package miner

// testminer.go implements the TestMiner interface, whose primary purpose is
// integration testing.

import (
	"bytes"
	"encoding/binary"
	"errors"
	"unsafe"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"
)

const (
	// solveAttempts is the number of times that SolveBlock will try to solve a
	// block before giving up.
	solveAttempts = 16e3
)

// solveBlock takes a block and a target and tries to solve the block for the
// target. A bool is returned indicating whether the block was successfully
// solved.
func solveBlock(b types.Block, target types.Target) (types.Block, bool) {
	// Assemble the header.
	merkleRoot := b.MerkleRoot()
	header := make([]byte, 80)
	copy(header, b.ParentID[:])
	binary.LittleEndian.PutUint64(header[40:48], uint64(b.Timestamp))
	copy(header[48:], merkleRoot[:])

	var nonce uint64
	for i := 0; i < solveAttempts; i++ {
		id := crypto.HashBytes(header)
		if bytes.Compare(target[:], id[:]) >= 0 {
			copy(b.Nonce[:], header[32:40])
			return b, true
		}
		*(*uint64)(unsafe.Pointer(&header[32])) = nonce
		nonce++
	}
	return b, false
}

// BlockForWork returns a block that is ready for nonce grinding, along with
// the root hash of the block.
func (m *Miner) BlockForWork() (b types.Block, t types.Target, err error) {
	// Check if the wallet is unlocked. If the wallet is unlocked, make sure
	// that the miner has a recent address.
	if !m.wallet.Unlocked() {
		err = modules.ErrLockedWallet
		return
	}
	m.mu.Lock()
	defer m.mu.Unlock()
	err = m.checkAddress()
	if err != nil {
		return
	}

	b = m.blockForWork()
	return b, m.persist.Target, nil
}

// AddBlock adds a block to the consensus set.
func (m *Miner) AddBlock() (types.Block, error) {
	block, err := m.FindBlock()
	if err != nil {
		return types.Block{}, err
	}
	err = m.cs.AcceptBlock(block)
	if err != nil {
		return types.Block{}, err
	}
	return block, nil
}

// FindBlock finds at most one block that extends the current blockchain.
func (m *Miner) FindBlock() (types.Block, error) {
	var bfw types.Block
	var target types.Target
	err := func() error {
		m.mu.Lock()
		defer m.mu.Unlock()

		if !m.wallet.Unlocked() {
			return modules.ErrLockedWallet
		}
		err := m.checkAddress()
		if err != nil {
			return err
		}

		// Get a block for work.
		bfw = m.blockForWork()
		target = m.persist.Target
		return nil
	}()
	if err != nil {
		return types.Block{}, err
	}

	block, ok := m.SolveBlock(bfw, target)
	if !ok {
		return types.Block{}, errors.New("could not solve block using limited hashing power")
	}
	return block, nil
}

// SolveBlock takes a block and a target and tries to solve the block for the
// target. A bool is returned indicating whether the block was successfully
// solved.
func (m *Miner) SolveBlock(b types.Block, target types.Target) (types.Block, bool) {
	return solveBlock(b, target)
}