func TestBuilder_StartSmeshingCoinbase(t *testing.T) {
	activationDb := newActivationDb(t)
	builder := newBuilder(t, activationDb)
	coinbase := types.Address{1, 1, 1}
	require.NoError(t, builder.StartSmeshing(coinbase, PostSetupOpts{}))
	t.Cleanup(func() { builder.StopSmeshing(true) })
	require.Equal(t, coinbase, builder.Coinbase())
}
========== Tests ==========
package activation
import (
	"context"
	"fmt"
	"testing"
	"time"
	"github.com/spacemeshos/ed25519"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/spacemeshos/go-spacemesh/common/types"
	"github.com/spacemeshos/go-spacemesh/common/util"
	"github.com/spacemeshos/go-spacemesh/database"
	"github.com/spacemeshos/go-spacemesh/log"
	"github.com/spacemeshos/go-spacemesh/log/logtest"
	"github.com/spacemeshos/go-spacemesh/mesh"
	"github.com/spacemeshos/go-spacemesh/rand"
	"github.com/spacemeshos/go-spacemesh/signing"
)
const (
	layersPerEpoch   = 10
	postGenesisEpoch = 2
)
func init() {
	types.SetLayersPerEpoch(layersPerEpoch)
}
var (
	pub, _, _   = ed25519.GenerateKey(nil)
	nodeID      = types.NodeID{Key: util.Bytes2Hex(pub), VRFPublicKey: []byte("22222")}
	otherNodeID = types.NodeID{Key: "00000", VRFPublicKey: []byte("00000")}
	coinbase    = types.HexToAddress("33333")
	goldenATXID = types.ATXID(types.HexToHash32("77777"))
	prevAtxID   = types.ATXID(types.HexToHash32("44444"))
	chlng       = types.HexToHash32("55555")
	poetRef     = types.BytesToHash([]byte("66666"))
	poetBytes   = []byte("66666")
	block1      = types.NewExistingBlock(types.LayerID{}, []byte("11111"), nil)
	block2      = types.NewExistingBlock(types.LayerID{}, []byte("22222"), nil)
	block3      = types.NewExistingBlock(types.LayerID{}, []byte("33333"), nil)
	postGenesisEpochLayer = types.NewLayerID(22)
	defaultMeshLayer      = types.NewLayerID(12)
	defaultView       = []types.BlockID{block1.ID(), block2.ID(), block3.ID()}
	net               = &NetMock{}
	layerClockMock    = &LayerClockMock{}
	meshProviderMock  = &MeshProviderMock{latestLayer: types.NewLayerID(12)}
	nipostBuilderMock = &NIPostBuilderMock{}
	nipost            = NewNIPostWithChallenge(&chlng, poetBytes)
	initialPost       = &types.Post{
		Nonce:   0,
		Indices: make([]byte, 10),
	}
)
type MeshProviderMock struct {
	GetOrphanBlocksBeforeFunc func(l types.LayerID) ([]types.BlockID, error)
	latestLayer               types.LayerID
}
func (mpm *MeshProviderMock) GetOrphanBlocksBefore(l types.LayerID) ([]types.BlockID, error) {
	if mpm.GetOrphanBlocksBeforeFunc != nil {
		return mpm.GetOrphanBlocksBeforeFunc(l)
	}
	return defaultView, nil
}
func (mpm *MeshProviderMock) LatestLayer() types.LayerID {
	layer := mpm.latestLayer
	mpm.latestLayer = defaultMeshLayer
	return layer
}
type NetMock struct {
	lastTransmission []byte
	atxDb            atxDBProvider
}
func (n *NetMock) Publish(_ context.Context, _ string, d []byte) error {
	n.lastTransmission = d
	go n.hookToAtxPool(d)
	return nil
}
func (n *NetMock) hookToAtxPool(transmission []byte) {
	if atx, err := types.BytesToAtx(transmission); err == nil {
		atx.CalcAndSetID()
		if n.atxDb != nil {
			if atxDb, ok := n.atxDb.(*DB); ok {
				err := atxDb.StoreAtx(context.TODO(), atx.PubLayerID.GetEpoch(), atx)
				if err != nil {
					panic(err)
				}
			}
		}
	}
}
type MockSigning struct{}
func (ms *MockSigning) Sign(m []byte) []byte {
	return m
}
type NIPostBuilderMock struct {
	updatedPoETs    []PoetProvingServiceClient
	poetRef         []byte
	buildNIPostFunc func(challenge *types.Hash32) (*types.NIPost, error)
	initPostFunc    func(logicalDrive string, commitmentSize uint64) (*types.Post, error)
	SleepTime       int
}
func (np NIPostBuilderMock) updatePoETProver(PoetProvingServiceClient) {}
func (np *NIPostBuilderMock) BuildNIPost(_ context.Context, challenge *types.Hash32, _ chan struct{}) (*types.NIPost, error) {
	if np.buildNIPostFunc != nil {
		return np.buildNIPostFunc(challenge)
	}
	return NewNIPostWithChallenge(challenge, np.poetRef), nil
}
type NIPostErrBuilderMock struct{}
func (np *NIPostErrBuilderMock) updatePoETProver(PoetProvingServiceClient) {}
func (np *NIPostErrBuilderMock) BuildNIPost(context.Context, *types.Hash32, chan struct{}) (*types.NIPost, error) {
	return nil, fmt.Errorf("NIPost builder error")
}
type MockIDStore struct{}
func (*MockIDStore) StoreNodeIdentity(types.NodeID) error {
	return nil
}
func (*MockIDStore) GetIdentity(string) (types.NodeID, error) {
	return types.NodeID{}, nil
}
type ValidatorMock struct{}
var _ nipostValidator = (*ValidatorMock)(nil)
func (*ValidatorMock) Validate(id signing.PublicKey, NIPost *types.NIPost, expectedChallenge types.Hash32, numUnits uint) error {
	return nil
}
func (*ValidatorMock) ValidatePost(id []byte, Post *types.Post, PostMetadata *types.PostMetadata, numUnits uint) error {
	return nil
}
func NewMockDB() *MockDB {
	return &MockDB{
		make(map[string][]byte),
		false,
	}
}
type MockDB struct {
	mp      map[string][]byte
	hadNone bool
}
func (m *MockDB) Put(key, val []byte) error {
	if len(val) == 0 {
		m.hadNone = true
	}
	m.mp[util.Bytes2Hex(key)] = val
	return nil
}
func (m *MockDB) Get(key []byte) ([]byte, error) {
	return m.mp[util.Bytes2Hex(key)], nil
}
type FaultyNetMock struct {
	bt     []byte
	retErr bool
}
func (n *FaultyNetMock) Publish(_ context.Context, _ string, d []byte) error {
	n.bt = d
	if n.retErr {
		return fmt.Errorf("faulty")
	}
	return nil
}
func newActivationDb(tb testing.TB) *DB {
	return NewDB(database.NewMemDatabase(), nil, &MockIDStore{}, mesh.NewMemMeshDB(logtest.New(tb).WithName("meshDB")), layersPerEpoch, goldenATXID, &ValidatorMock{}, logtest.New(tb).WithName("atxDB"))
}
func newChallenge(nodeID types.NodeID, sequence uint64, prevAtxID, posAtxID types.ATXID, pubLayerID types.LayerID) types.NIPostChallenge {
	challenge := types.NIPostChallenge{
		NodeID:         nodeID,
		Sequence:       sequence,
		PrevATXID:      prevAtxID,
		PubLayerID:     pubLayerID,
		StartTick:      100 * sequence,
		EndTick:        100 * (sequence + 1),
		PositioningATX: posAtxID,
	}
	return challenge
}
func newAtx(challenge types.NIPostChallenge, nipost *types.NIPost) *types.ActivationTx {
	activationTx := &types.ActivationTx{
		InnerActivationTx: &types.InnerActivationTx{
			ActivationTxHeader: &types.ActivationTxHeader{
				NIPostChallenge: challenge,
				NumUnits:        2,
				Coinbase:        coinbase,
			},
			NIPost: nipost,
		},
	}
	activationTx.CalcAndSetID()
	return activationTx
}
type LayerClockMock struct {
	currentLayer types.LayerID
}
func (l *LayerClockMock) GetCurrentLayer() types.LayerID {
	return l.currentLayer
}
func (l *LayerClockMock) AwaitLayer(types.LayerID) chan struct{} {
	ch := make(chan struct{})
	go func() {
		time.Sleep(500 * time.Millisecond)
		close(ch)
	}()
	return ch
}
type mockSyncer struct{}
func (m *mockSyncer) RegisterChForSynced(_ context.Context, ch chan struct{}) {
	close(ch)
}
func newBuilder(tb testing.TB, activationDb atxDBProvider) *Builder {
	net.atxDb = activationDb
	cfg := Config{
		CoinbaseAccount: coinbase,
		GoldenATXID:     goldenATXID,
		LayersPerEpoch:  layersPerEpoch,
	}
	b := NewBuilder(cfg, nodeID, &MockSigning{}, activationDb, net, meshProviderMock, layersPerEpoch, nipostBuilderMock, &postSetupProviderMock{},
		layerClockMock, &mockSyncer{}, NewMockDB(), logtest.New(tb).WithName("atxBuilder"))
	b.initialPost = initialPost
	return b
}
func lastTransmittedAtx(t *testing.T) types.ActivationTx {
	var signedAtx types.ActivationTx
	err := types.BytesToInterface(net.lastTransmission, &signedAtx)
	require.NoError(t, err)
	return signedAtx
}
func assertLastAtx(r *require.Assertions, posAtx, prevAtx *types.ActivationTxHeader, layersPerEpoch uint32) {
	sigAtx, err := types.BytesToAtx(net.lastTransmission)
	r.NoError(err)
	atx := sigAtx
	r.Equal(nodeID, atx.NodeID)
	if prevAtx != nil {
		r.Equal(prevAtx.Sequence+1, atx.Sequence)
		r.Equal(prevAtx.ID(), atx.PrevATXID)
		r.Nil(atx.InitialPost)
		r.Nil(atx.InitialPostIndices)
	} else {
		r.Zero(atx.Sequence)
		r.Equal(*types.EmptyATXID, atx.PrevATXID)
		r.NotNil(atx.InitialPost)
		r.NotNil(atx.InitialPostIndices)
	}
	r.Equal(posAtx.ID(), atx.PositioningATX)
	r.Equal(posAtx.PubLayerID.Add(layersPerEpoch), atx.PubLayerID)
	r.Equal(poetRef, atx.GetPoetProofRef())
}
func storeAtx(r *require.Assertions, activationDb *DB, atx *types.ActivationTx, lg log.Log) {
	epoch := atx.PubLayerID.GetEpoch()
	lg.Info("stored ATX in epoch %v", epoch)
	err := activationDb.StoreAtx(context.TODO(), epoch, atx)
	r.NoError(err)
}
func publishAtx(b *Builder, meshLayer types.LayerID, clockEpoch types.EpochID, buildNIPostLayerDuration uint32) (published, builtNIPost bool, err error) {
	net.lastTransmission = nil
	meshProviderMock.latestLayer = meshLayer
	nipostBuilderMock.buildNIPostFunc = func(challenge *types.Hash32) (*types.NIPost, error) {
		builtNIPost = true
		meshProviderMock.latestLayer = meshLayer.Add(buildNIPostLayerDuration)
		layerClockMock.currentLayer = layerClockMock.currentLayer.Add(buildNIPostLayerDuration)
		return NewNIPostWithChallenge(challenge, poetBytes), nil
	}
	layerClockMock.currentLayer = clockEpoch.FirstLayer().Add(3)
	err = b.PublishActivationTx(context.TODO())
	nipostBuilderMock.buildNIPostFunc = nil
	return net.lastTransmission != nil, builtNIPost, err
}