func (em *Emitter) Stop() {
	if em.done == nil {
		return
	}
	close(em.done)
	em.done = nil
	em.wg.Wait()
	em.busyRate.Stop()
}
Stop stops event emission.
package emitter
import (
	"fmt"
	"math/rand"
	"os"
	"strings"
	"sync"
	"time"
	"github.com/Fantom-foundation/lachesis-base/emitter/ancestor"
	"github.com/Fantom-foundation/lachesis-base/hash"
	"github.com/Fantom-foundation/lachesis-base/inter/idx"
	"github.com/Fantom-foundation/lachesis-base/inter/pos"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/trie"
	lru "github.com/hashicorp/golang-lru"
	"github.com/Fantom-foundation/go-opera/evmcore"
	"github.com/Fantom-foundation/go-opera/gossip/emitter/originatedtxs"
	"github.com/Fantom-foundation/go-opera/inter"
	"github.com/Fantom-foundation/go-opera/logger"
	"github.com/Fantom-foundation/go-opera/tracing"
	"github.com/Fantom-foundation/go-opera/utils/piecefunc"
	"github.com/Fantom-foundation/go-opera/utils/rate"
)
const (
	SenderCountBufferSize = 20000
	PayloadIndexerSize    = 5000
)
type Emitter struct {
	txTime *lru.Cache  
	config Config
	world World
	syncStatus syncStatus
	prevIdleTime       time.Time
	prevEmittedAtTime  time.Time
	prevEmittedAtBlock idx.Block
	originatedTxs      *originatedtxs.Buffer
	pendingGas         uint64
	validators *pos.Validators
	epoch      idx.Epoch
	challenges map[idx.ValidatorID]time.Time
	offlineValidators     map[idx.ValidatorID]bool
	expectedEmitIntervals map[idx.ValidatorID]time.Duration
	stakeRatio            map[idx.ValidatorID]uint64
	prevRecheckedChallenges time.Time
	quorumIndexer  *ancestor.QuorumIndexer
	payloadIndexer *ancestor.PayloadIndexer
	intervals EmitIntervals
	done chan struct{}
	wg   sync.WaitGroup
	maxParents idx.Event
	cache struct {
		sortedTxs *types.TransactionsByPriceAndNonce
		poolTime  time.Time
		poolBlock idx.Block
		poolCount int
	}
	emittedEventFile *os.File
	busyRate         *rate.Gauge
	logger.Periodic
}
func NewEmitter(
	config Config,
	world World,
) *Emitter {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	config.EmitIntervals = config.EmitIntervals.RandomizeEmitTime(r)
	txTime, _ := lru.New(TxTimeBufferSize)
	return &Emitter{
		config:        config,
		world:         world,
		originatedTxs: originatedtxs.New(SenderCountBufferSize),
		txTime:        txTime,
		intervals:     config.EmitIntervals,
		Periodic:      logger.Periodic{Instance: logger.MakeInstance()},
	}
}
func (em *Emitter) init() {
	em.syncStatus.startup = time.Now()
	em.syncStatus.lastConnected = time.Now()
	em.syncStatus.p2pSynced = time.Now()
	validators, epoch := em.world.GetEpochValidators()
	em.OnNewEpoch(validators, epoch)
	if len(em.config.PrevEmittedEventFile.Path) != 0 {
		em.emittedEventFile = openEventFile(em.config.PrevEmittedEventFile.Path, em.config.PrevEmittedEventFile.SyncMode)
	}
	em.busyRate = rate.NewGauge()
}
func (em *Emitter) Start() {
	if em.config.Validator.ID == 0 {
		return
	}
	if em.done != nil {
		return
	}
	em.init()
	em.done = make(chan struct{})
	newTxsCh := make(chan evmcore.NewTxsNotify)
	em.world.TxPool.SubscribeNewTxsNotify(newTxsCh)
	done := em.done
	em.wg.Add(1)
	go func() {
		defer em.wg.Done()
		tick := 11 * time.Millisecond
		timer := time.NewTimer(tick)
		defer timer.Stop()
		for {
			select {
			case txNotify := <-newTxsCh:
				em.memorizeTxTimes(txNotify.Txs)
			case <-timer.C:
				em.tick()
			case <-done:
				return
			}
			timer.Reset(tick)
		}
	}()
}