package service import ( "context" "net" "github.com/ethereum-optimism/optimism/op-ufm/pkg/config" "github.com/ethereum-optimism/optimism/op-ufm/pkg/metrics" "github.com/ethereum-optimism/optimism/op-ufm/pkg/provider" "github.com/ethereum/go-ethereum/log" ) type Service struct { Config *config.Config Healthz *HealthzServer Metrics *MetricsServer Providers map[string]*provider.Provider } func New(cfg *config.Config) *Service { s := &Service{ Config: cfg, Healthz: &HealthzServer{}, Metrics: &MetricsServer{}, Providers: make(map[string]*provider.Provider, len(cfg.Providers)), } return s } func (s *Service) Start(ctx context.Context) { log.Info("service starting") if s.Config.Healthz.Enabled { addr := net.JoinHostPort(s.Config.Healthz.Host, s.Config.Healthz.Port) log.Info("starting healthz server", "addr", addr) go func() { if err := s.Healthz.Start(ctx, addr); err != nil { log.Error("error starting healthz server", "err", err) } }() } metrics.Debug = s.Config.Metrics.Debug if s.Config.Metrics.Enabled { addr := net.JoinHostPort(s.Config.Metrics.Host, s.Config.Metrics.Port) log.Info("starting metrics server", "addr", addr) go func() { if err := s.Metrics.Start(ctx, addr); err != nil { log.Error("error starting metrics server", "err", err) } }() } // map networks to its providers networks := make(map[string][]string) for name, providerConfig := range s.Config.Providers { networks[providerConfig.Network] = append(networks[providerConfig.Network], name) } txpool := &provider.TransactionPool{} for name, providers := range networks { if len(providers) == 1 { log.Warn("can't measure first seen for network, please another provider", "network", name) } (*txpool)[name] = &provider.NetworkTransactionPool{} (*txpool)[name].Transactions = make(map[string]*provider.TransactionState) // set expected number of providers for this network // -1 since we don't wait for acking from the same provider (*txpool)[name].Expected = len(providers) - 1 } for name, providerConfig := range s.Config.Providers { s.Providers[name] = provider.New(name, providerConfig, &s.Config.Signer, s.Config.Wallets[providerConfig.Wallet], (*txpool)[providerConfig.Network]) s.Providers[name].Start(ctx) log.Info("provider started", "provider", name) } log.Info("service started") } func (s *Service) Shutdown() { log.Info("service shutting down") if s.Config.Healthz.Enabled { if err := s.Healthz.Shutdown(); err != nil { log.Error("Error shutting down healthz server", err) } log.Info("healthz stopped") } if s.Config.Metrics.Enabled { if err := s.Metrics.Shutdown(); err != nil { log.Error("Error shutting down metrics server", err) } log.Info("metrics stopped") } for name, provider := range s.Providers { provider.Shutdown() log.Info("provider stopped", "provider", name) } log.Info("service stopped") }