func (m *Miner) managedSubmitBlock(b types.Block) error {
	err := m.cs.AcceptBlock(b)
	if err == modules.ErrNonExtendingBlock {
		m.mu.Lock()
		m.persist.BlocksFound = append(m.persist.BlocksFound, b.ID())
		m.mu.Unlock()
		m.log.Println("Mined a stale block - block appears valid but does not extend the blockchain")
		return err
	}
	if err == modules.ErrBlockUnsolved {
		m.log.Println("Mined an unsolved block - header submission appears to be incorrect")
		return err
	}
	if err != nil {
		m.tpool.PurgeTransactionPool()
		m.log.Critical("ERROR: an invalid block was submitted:", err)
		return err
	}
	m.mu.Lock()
	defer m.mu.Unlock()
	m.persist.BlocksFound = append(m.persist.BlocksFound, b.ID())
	var uc types.UnlockConditions
	uc, err = m.wallet.NextAddress()
	if err != nil {
		return err
	}
	m.persist.Address = uc.UnlockHash()
	return m.saveSync()
}
managedSubmitBlock takes a solved block and submits it to the blockchain.
package miner
import (
	"errors"
	"time"
	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"
	"github.com/NebulousLabs/fastrand"
)
var (
	errLateHeader = errors.New("header is old, block could not be recovered")
)
func (m *Miner) blockForWork() types.Block {
	b := m.persist.UnsolvedBlock
	if b.Timestamp < types.CurrentTimestamp() {
		b.Timestamp = types.CurrentTimestamp()
	}
	err := m.checkAddress()
	if err != nil {
		m.log.Println(err)
	}
	b.MinerPayouts = []types.SiacoinOutput{{
		Value:      b.CalculateSubsidy(m.persist.Height + 1),
		UnlockHash: m.persist.Address,
	}}
	randBytes := fastrand.Bytes(types.SpecifierLen)
	randTxn := types.Transaction{
		ArbitraryData: [][]byte{append(modules.PrefixNonSia[:], randBytes...)},
	}
	b.Transactions = append([]types.Transaction{randTxn}, b.Transactions...)
	return b
}
func (m *Miner) newSourceBlock() {
	for m.memProgress%(HeaderMemory/BlockMemory) != 0 {
		delete(m.blockMem, m.headerMem[m.memProgress])
		delete(m.arbDataMem, m.headerMem[m.memProgress])
		m.memProgress++
		if m.memProgress == HeaderMemory {
			m.memProgress = 0
		}
	}
	block := m.blockForWork()
	m.sourceBlock = &block
	m.sourceBlockTime = time.Now()
}
func (m *Miner) HeaderForWork() (types.BlockHeader, types.Target, error) {
	if err := m.tg.Add(); err != nil {
		return types.BlockHeader{}, types.Target{}, err
	}
	defer m.tg.Done()
	m.mu.Lock()
	defer m.mu.Unlock()
	unlocked, err := m.wallet.Unlocked()
	if err != nil {
		return types.BlockHeader{}, types.Target{}, err
	}
	if !unlocked {
		return types.BlockHeader{}, types.Target{}, modules.ErrLockedWallet
	}
	err = m.checkAddress()
	if err != nil {
		return types.BlockHeader{}, types.Target{}, err
	}
	if time.Since(m.sourceBlockTime) > MaxSourceBlockAge || m.memProgress%(HeaderMemory/BlockMemory) == 0 {
		m.newSourceBlock()
	}
	var arbData [crypto.EntropySize]byte
	fastrand.Read(arbData[:])
	copy(m.sourceBlock.Transactions[0].ArbitraryData[0], arbData[:])
	header := m.sourceBlock.Header()
	delete(m.blockMem, m.headerMem[m.memProgress])
	delete(m.arbDataMem, m.headerMem[m.memProgress])
	m.blockMem[header] = m.sourceBlock
	m.arbDataMem[header] = arbData
	m.headerMem[m.memProgress] = header
	m.memProgress++
	if m.memProgress == HeaderMemory {
		m.memProgress = 0
	}
	return header, m.persist.Target, nil
}