func TestIntegrationAutoRescan(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	mt, err := createMinerTester(t.Name())
	if err != nil {
		t.Fatal(err)
	}
	_, err = mt.miner.AddBlock()
	if err != nil {
		t.Fatal(err)
	}
	oldChange := mt.miner.persist.RecentChange
	oldHeight := mt.miner.persist.Height
	oldTarget := mt.miner.persist.Target
	mt.miner.persist.RecentChange[0]++
	mt.miner.persist.Height += 1e5
	mt.miner.persist.Target[0]++
	err = mt.miner.Close()  
	if err != nil {
		t.Fatal(err)
	}
	m, err := New(mt.cs, mt.tpool, mt.wallet, filepath.Join(mt.persistDir, modules.MinerDir))
	if err != nil {
		t.Fatal(err)
	}
	if m.persist.RecentChange != oldChange {
		t.Error("rescan failed, ended up on the wrong change")
	}
	if m.persist.Height != oldHeight {
		t.Error("rescan failed, ended up at the wrong height")
	}
	if m.persist.Target != oldTarget {
		t.Error("rescan failed, ended up at the wrong target")
	}
}
TestIntegrationAutoRescan triggers a rescan during a call to New and
verifies that the rescanning happens correctly. The rescan is triggered by
a call to New, instead of getting called directly.
package miner
import (
	"bytes"
	"path/filepath"
	"testing"
	"time"
	"github.com/NebulousLabs/Sia/build"
	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/modules/consensus"
	"github.com/NebulousLabs/Sia/modules/gateway"
	"github.com/NebulousLabs/Sia/modules/transactionpool"
	"github.com/NebulousLabs/Sia/modules/wallet"
	"github.com/NebulousLabs/Sia/types"
	"github.com/NebulousLabs/fastrand"
)
type minerTester struct {
	gateway   modules.Gateway
	cs        modules.ConsensusSet
	tpool     modules.TransactionPool
	wallet    modules.Wallet
	walletKey crypto.TwofishKey
	miner *Miner
	minedBlocks []types.Block
	persistDir  string
}
func createMinerTester(name string) (*minerTester, error) {
	testdir := build.TempDir(modules.MinerDir, name)
	g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir))
	if err != nil {
		return nil, err
	}
	cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir))
	if err != nil {
		return nil, err
	}
	tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir))
	if err != nil {
		return nil, err
	}
	w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir))
	if err != nil {
		return nil, err
	}
	var key crypto.TwofishKey
	fastrand.Read(key[:])
	_, err = w.Encrypt(key)
	if err != nil {
		return nil, err
	}
	err = w.Unlock(key)
	if err != nil {
		return nil, err
	}
	m, err := New(cs, tp, w, filepath.Join(testdir, modules.MinerDir))
	if err != nil {
		return nil, err
	}
	mt := &minerTester{
		gateway:   g,
		cs:        cs,
		tpool:     tp,
		wallet:    w,
		walletKey: key,
		miner: m,
		persistDir: testdir,
	}
	for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ {
		b, err := m.AddBlock()
		if err != nil {
			return nil, err
		}
		mt.minedBlocks = append(mt.minedBlocks, b)
	}
	return mt, nil
}
func TestIntegrationMiner(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	mt, err := createMinerTester(t.Name())
	if err != nil {
		t.Fatal(err)
	}
	siacoins, _, _, err := mt.wallet.ConfirmedBalance()
	if err != nil {
		t.Error(err)
	}
	if siacoins.IsZero() {
		t.Error("expecting mining full balance to not be zero")
	}
	for i := 0; i < 50; i++ {
		b, _ := mt.miner.FindBlock()
		err = mt.cs.AcceptBlock(b)
		if err != nil {
			t.Fatal(err)
		}
	}
	morecoins, _, _, err := mt.wallet.ConfirmedBalance()
	if err != nil {
		t.Error(err)
	}
	if siacoins.Cmp(morecoins) >= 0 {
		t.Error("wallet is not gaining balance while mining")
	}
}
func TestIntegrationNilMinerDependencies(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	mt, err := createMinerTester(t.Name())
	if err != nil {
		t.Fatal(err)
	}
	_, err = New(mt.cs, mt.tpool, nil, "")
	if err != errNilWallet {
		t.Fatal(err)
	}
	_, err = New(mt.cs, nil, mt.wallet, "")
	if err != errNilTpool {
		t.Fatal(err)
	}
	_, err = New(nil, mt.tpool, mt.wallet, "")
	if err != errNilCS {
		t.Fatal(err)
	}
	_, err = New(nil, nil, nil, "")
	if err == nil {
		t.Fatal(err)
	}
}
func TestIntegrationBlocksMined(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	mt, err := createMinerTester(t.Name())
	if err != nil {
		t.Fatal(err)
	}
	unsolvedHeader, target, err := mt.miner.HeaderForWork()
	if err != nil {
		t.Fatal(err)
	}
	for {
		unsolvedHeader.Nonce[0]++
		id := crypto.HashObject(unsolvedHeader)
		if bytes.Compare(target[:], id[:]) < 0 {
			break
		}
	}
	header1, target, err := mt.miner.HeaderForWork()
	if err != nil {
		t.Fatal(err)
	}
	header1 = solveHeader(header1, target)
	header2, target, err := mt.miner.HeaderForWork()
	if err != nil {
		t.Fatal(err)
	}
	header2 = solveHeader(header2, target)
	err = mt.miner.SubmitHeader(unsolvedHeader)
	if err != modules.ErrBlockUnsolved {
		t.Fatal(err)
	}
	err = mt.miner.SubmitHeader(header1)
	if err != nil {
		t.Fatal(err)
	}
	err = mt.miner.SubmitHeader(header2)
	if err != modules.ErrNonExtendingBlock {
		t.Fatal(err)
	}
	goodBlocks, staleBlocks := mt.miner.BlocksMined()
	if goodBlocks != 1 {
		t.Error("expecting 1 good block")
	}
	if staleBlocks != 1 {
		t.Error("expecting 1 stale block, got", staleBlocks)
	}
	err = mt.miner.Close()
	if err != nil {
		t.Fatal(err)
	}
	rebootMiner, err := New(mt.cs, mt.tpool, mt.wallet, filepath.Join(mt.persistDir, modules.MinerDir))
	if err != nil {
		t.Fatal(err)
	}
	goodBlocks, staleBlocks = rebootMiner.BlocksMined()
	if goodBlocks != 1 {
		t.Error("expecting 1 good block")
	}
	if staleBlocks != 1 {
		t.Error("expecting 1 stale block, got", staleBlocks)
	}
}