func (es *EventSystem) subscribe(sub *subscription) *Subscription {
	es.install <- sub
	<-sub.installed
	return &Subscription{ID: sub.id, f: sub, es: es}
}
subscribe installs the subscription in the event broadcast loop.
package filters
import (
	"errors"
	"fmt"
	"sync"
	"time"
	ethereum "github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/core/types"
	notify "github.com/ethereum/go-ethereum/event"
	"github.com/ethereum/go-ethereum/log"
	"github.com/ethereum/go-ethereum/rpc"
	"github.com/Fantom-foundation/go-opera/evmcore"
)
type Type byte
const (
	UnknownSubscription Type = iota
	LogsSubscription
	PendingLogsSubscription
	MinedAndPendingLogsSubscription
	PendingTransactionsSubscription
	BlocksSubscription
	LastIndexSubscription
)
const (
	txChanSize = 4096
	logsChanSize = 10
	blocksChanSize = 10
)
var (
	ErrInvalidSubscriptionID = errors.New("invalid id")
)
type subscription struct {
	id        rpc.ID
	typ       Type
	created   time.Time
	logsCrit  ethereum.FilterQuery
	logs      chan []*types.Log
	hashes    chan []common.Hash
	headers   chan *types.Header
	installed chan struct{}  
	err       chan error     
}
type EventSystem struct {
	backend Backend
	txsSub    notify.Subscription  
	logsSub   notify.Subscription  
	blocksSub notify.Subscription  
	install   chan *subscription            
	uninstall chan *subscription            
	txsCh     chan core.NewTxsEvent         
	logsCh    chan []*types.Log             
	blocksCh  chan evmcore.ChainHeadNotify  
}
func NewEventSystem(backend Backend) *EventSystem {
	m := &EventSystem{
		backend:   backend,
		install:   make(chan *subscription),
		uninstall: make(chan *subscription),
		blocksCh:  make(chan evmcore.ChainHeadNotify, blocksChanSize),
		txsCh:     make(chan core.NewTxsEvent, txChanSize),
		logsCh:    make(chan []*types.Log, logsChanSize),
	}
	m.blocksSub = m.backend.SubscribeNewBlockEvent(m.blocksCh)
	m.txsSub = m.backend.SubscribeNewTxsEvent(m.txsCh)
	m.logsSub = m.backend.SubscribeLogsEvent(m.logsCh)
	if m.txsSub == nil || m.logsSub == nil || m.blocksSub == nil {
		log.Crit("Subscribe for event system failed")
	}
	go m.eventLoop()
	return m
}
type Subscription struct {
	ID        rpc.ID
	f         *subscription
	es        *EventSystem
	unsubOnce sync.Once
}
func (sub *Subscription) Err() <-chan error {
	return sub.f.err
}
func (sub *Subscription) Unsubscribe() {
	sub.unsubOnce.Do(func() {
	uninstallLoop:
		for {
			select {
			case sub.es.uninstall <- sub.f:
				break uninstallLoop
			case <-sub.f.logs:
			case <-sub.f.hashes:
			case <-sub.f.headers:
			}
		}
		<-sub.Err()
	})
}