From 900d5579eee42ce9f62dcd3b17dfed76d47a7707 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 30 Oct 2023 12:12:52 -0500 Subject: [PATCH] pkg/loop: plugins report health to host --- pkg/logger/logger.go | 7 + pkg/loop/ccip_commit.go | 11 +- pkg/loop/ccip_commit_test.go | 10 +- pkg/loop/ccip_execution.go | 11 +- pkg/loop/ccip_execution_test.go | 8 +- .../ocr2/reporting_plugin_service.go | 6 + .../ocr2/test/factory_servers.go | 43 +++-- .../ocr3/reporting_plugin_service.go | 6 + .../reportingplugin/ocr3/test/factory.go | 35 ++-- .../ocr3/test/factory_generators.go | 43 +++-- pkg/loop/internal/goplugin/plugin_service.go | 30 ++- pkg/loop/internal/goplugin/service.go | 9 +- .../contractreader/test/contract_reader.go | 10 - .../ext/ccip/test/commit_factory_server.go | 28 ++- .../ext/ccip/test/commit_provider.go | 45 ++--- .../ext/ccip/test/commit_provider_test.go | 13 +- .../ext/ccip/test/commit_store.go | 18 +- .../ext/ccip/test/commit_store_test.go | 67 ++++--- .../ext/ccip/test/exec_factory_server.go | 29 ++- .../ext/ccip/test/exec_provider.go | 45 ++--- .../ext/ccip/test/exec_provider_test.go | 17 +- .../pluginprovider/ext/median/test/median.go | 71 ++++--- .../pluginprovider/ext/median/test/test.go | 61 +++--- .../ext/mercury/test/mercury.go | 66 ++++--- .../ext/mercury/test/provider.go | 26 +-- .../pluginprovider/ocr2/test/config.go | 25 +-- .../ocr2/test/plugin_provider.go | 30 ++- .../relayer/pluginprovider/ocr2/test/test.go | 38 ++-- pkg/loop/internal/relayer/relayer.go | 10 +- pkg/loop/internal/relayer/test/relayer.go | 181 +++++++++++------- .../internal/reportingplugin/median/median.go | 5 + .../internal/reportingplugin/test/factory.go | 38 ++-- pkg/loop/internal/test/cmd/main.go | 20 +- pkg/loop/internal/test/test.go | 32 ++++ pkg/loop/internal/test/types/interfaces.go | 1 - pkg/loop/internal/types/types.go | 1 + pkg/loop/keystore_service.go | 7 +- pkg/loop/median_service.go | 12 +- pkg/loop/median_service_test.go | 15 +- pkg/loop/mercury_service.go | 42 ++-- pkg/loop/mercury_service_test.go | 40 ++-- pkg/loop/plugin_median.go | 1 + pkg/loop/plugin_median_test.go | 10 +- pkg/loop/plugin_mercury_test.go | 11 +- pkg/loop/plugin_relayer.go | 1 + pkg/loop/plugin_relayer_test.go | 3 +- pkg/loop/process_test.go | 9 +- pkg/loop/relayer_service.go | 13 +- pkg/loop/relayer_service_test.go | 69 +++++-- pkg/loop/reportingplugins/grpc.go | 2 + pkg/loop/reportingplugins/grpc_test.go | 10 +- pkg/loop/reportingplugins/loopp_service.go | 22 ++- pkg/loop/reportingplugins/ocr3/grpc.go | 2 + pkg/loop/reportingplugins/ocr3/grpc_test.go | 8 +- .../reportingplugins/ocr3/loopp_service.go | 21 +- pkg/loop/standard_capabilities.go | 6 +- pkg/services/servicetest/health.go | 4 +- pkg/services/servicetest/run.go | 4 +- pkg/types/contract_reader.go | 4 +- pkg/types/core/median.go | 2 + pkg/types/core/reporting_plugin_service.go | 4 + pkg/types/provider_ccip.go | 3 + pkg/types/provider_mercury.go | 2 + 63 files changed, 894 insertions(+), 529 deletions(-) diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 74af6ff39..28a7cd1f8 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -164,6 +164,13 @@ func With(l Logger, keyvals ...interface{}) Logger { // Named returns a logger with name 'n', if 'l' has a method `Named(string) L`, where L implements Logger, otherwise it returns l. func Named(l Logger, n string) Logger { + l = named(l, n) + if testing.Testing() { + l.Debugf("New logger: %s", n) + } + return l +} +func named(l Logger, n string) Logger { switch t := l.(type) { case *logger: return t.named(n) diff --git a/pkg/loop/ccip_commit.go b/pkg/loop/ccip_commit.go index 598f06096..5504f4e52 100644 --- a/pkg/loop/ccip_commit.go +++ b/pkg/loop/ccip_commit.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/goplugin" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/reportingplugin/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" ) @@ -69,12 +70,16 @@ type CommitFactoryService struct { // NewCommitService returns a new [*CommitFactoryService]. // cmd must return a new exec.Cmd each time it is called. func NewCommitService(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, provider types.CCIPCommitProvider) *CommitFactoryService { - newService := func(ctx context.Context, instance any) (types.ReportingPluginFactory, error) { + newService := func(ctx context.Context, instance any) (types.ReportingPluginFactory, services.HealthReporter, error) { plug, ok := instance.(types.CCIPCommitFactoryGenerator) if !ok { - return nil, fmt.Errorf("expected CCIPCommitFactoryGenerator but got %T", instance) + return nil, nil, fmt.Errorf("expected CCIPCommitFactoryGenerator but got %T", instance) } - return plug.NewCommitFactory(ctx, provider) + factory, err := plug.NewCommitFactory(ctx, provider) + if err != nil { + return nil, nil, err + } + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "CCIPCommitService") diff --git a/pkg/loop/ccip_commit_test.go b/pkg/loop/ccip_commit_test.go index c3956ffd8..5f62b9ffa 100644 --- a/pkg/loop/ccip_commit_test.go +++ b/pkg/loop/ccip_commit_test.go @@ -26,9 +26,10 @@ import ( func TestCommitService(t *testing.T) { t.Parallel() - commit := loop.NewCommitService(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + lggr := logger.Test(t) + commit := loop.NewCommitService(lggr, loop.GRPCOpts{}, func() *exec.Cmd { return NewHelperProcessCommand(loop.CCIPCommitLOOPName, false, 0) - }, cciptest.CommitProvider) + }, cciptest.CommitProvider(lggr)) t.Run("service not nil", func(t *testing.T) { require.NotPanics(t, func() { commit.Name() }) @@ -62,14 +63,15 @@ func TestCommitService(t *testing.T) { func TestCommitService_recovery(t *testing.T) { t.Parallel() + lggr := logger.Test(t) var limit atomic.Int32 - commit := loop.NewCommitService(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + commit := loop.NewCommitService(lggr, loop.GRPCOpts{}, func() *exec.Cmd { h := HelperProcessCommand{ Command: loop.CCIPCommitLOOPName, Limit: int(limit.Add(1)), } return h.New() - }, cciptest.CommitProvider) + }, cciptest.CommitProvider(lggr)) servicetest.Run(t, commit) reportingplugintest.RunFactory(t, commit) diff --git a/pkg/loop/ccip_execution.go b/pkg/loop/ccip_execution.go index 2df482a35..4c95d7c3f 100644 --- a/pkg/loop/ccip_execution.go +++ b/pkg/loop/ccip_execution.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/goplugin" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/reportingplugin/ccip" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" ) @@ -69,12 +70,16 @@ type ExecutionFactoryService struct { // NewExecutionService returns a new [*ExecutionFactoryService]. // cmd must return a new exec.Cmd each time it is called. func NewExecutionService(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, srcProvider types.CCIPExecProvider, dstProvider types.CCIPExecProvider, srcChain uint32, dstChain uint32, sourceTokenAddress string) *ExecutionFactoryService { - newService := func(ctx context.Context, instance any) (types.ReportingPluginFactory, error) { + newService := func(ctx context.Context, instance any) (types.ReportingPluginFactory, services.HealthReporter, error) { plug, ok := instance.(types.CCIPExecutionFactoryGenerator) if !ok { - return nil, fmt.Errorf("expected CCIPExecutionFactoryGenerator but got %T", instance) + return nil, nil, fmt.Errorf("expected CCIPExecutionFactoryGenerator but got %T", instance) } - return plug.NewExecutionFactory(ctx, srcProvider, dstProvider, int64(srcChain), int64(dstChain), sourceTokenAddress) + factory, err := plug.NewExecutionFactory(ctx, srcProvider, dstProvider, int64(srcChain), int64(dstChain), sourceTokenAddress) + if err != nil { + return nil, nil, err + } + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "CCIPExecutionService") diff --git a/pkg/loop/ccip_execution_test.go b/pkg/loop/ccip_execution_test.go index b26f44bdf..69f42312c 100644 --- a/pkg/loop/ccip_execution_test.go +++ b/pkg/loop/ccip_execution_test.go @@ -26,9 +26,10 @@ import ( func TestExecService(t *testing.T) { t.Parallel() + lggr := logger.Test(t) exec := loop.NewExecutionService(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { return NewHelperProcessCommand(loop.CCIPExecutionLOOPName, false, 0) - }, cciptest.ExecutionProvider, cciptest.ExecutionProvider, 0, 0, "") + }, cciptest.ExecutionProvider(lggr), cciptest.ExecutionProvider(lggr), 0, 0, "") hook := exec.PluginService.XXXTestHook() servicetest.Run(t, exec) @@ -57,14 +58,15 @@ func TestExecService(t *testing.T) { func TestExecService_recovery(t *testing.T) { t.Parallel() + lggr := logger.Test(t) var limit atomic.Int32 - exec := loop.NewExecutionService(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + exec := loop.NewExecutionService(lggr, loop.GRPCOpts{}, func() *exec.Cmd { h := HelperProcessCommand{ Command: loop.CCIPExecutionLOOPName, Limit: int(limit.Add(1)), } return h.New() - }, cciptest.ExecutionProvider, cciptest.ExecutionProvider, 0, 0, "") + }, cciptest.ExecutionProvider(lggr), cciptest.ExecutionProvider(lggr), 0, 0, "") servicetest.Run(t, exec) reportingplugintest.RunFactory(t, exec) diff --git a/pkg/loop/internal/core/services/reportingplugin/ocr2/reporting_plugin_service.go b/pkg/loop/internal/core/services/reportingplugin/ocr2/reporting_plugin_service.go index ca2761b1b..5904c0c67 100644 --- a/pkg/loop/internal/core/services/reportingplugin/ocr2/reporting_plugin_service.go +++ b/pkg/loop/internal/core/services/reportingplugin/ocr2/reporting_plugin_service.go @@ -149,6 +149,7 @@ type reportingPluginServiceServer struct { } func RegisterReportingPluginServiceServer(server *grpc.Server, broker net.Broker, brokerCfg net.BrokerConfig, impl core.ReportingPluginClient) error { + pb.RegisterServiceServer(server, &goplugin.ServiceServer{Srv: impl}) pb.RegisterReportingPluginServiceServer(server, newReportingPluginServiceServer(&net.BrokerExt{Broker: broker, BrokerConfig: brokerCfg}, impl)) return nil } @@ -218,6 +219,11 @@ func (m *reportingPluginServiceServer) NewReportingPluginFactory(ctx context.Con m.CloseAll(providerRes, errorLogRes, pipelineRunnerRes, telemetryRes, keyValueStoreRes, relayerSetRes) return nil, err } + //TODO start factory - when to close? + if err = factory.Start(ctx); err != nil { + m.CloseAll(providerRes, errorLogRes, pipelineRunnerRes, telemetryRes, keyValueStoreRes, relayerSetRes) + return nil, err + } id, _, err := m.ServeNew("ReportingPluginProvider", func(s *grpc.Server) { pb.RegisterServiceServer(s, &goplugin.ServiceServer{Srv: factory}) diff --git a/pkg/loop/internal/core/services/reportingplugin/ocr2/test/factory_servers.go b/pkg/loop/internal/core/services/reportingplugin/ocr2/test/factory_servers.go index d5459de92..1cec5c685 100644 --- a/pkg/loop/internal/core/services/reportingplugin/ocr2/test/factory_servers.go +++ b/pkg/loop/internal/core/services/reportingplugin/ocr2/test/factory_servers.go @@ -6,6 +6,7 @@ import ( "google.golang.org/grpc" + "github.com/smartcontractkit/chainlink-common/pkg/logger" pipelinetest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/pipeline/test" telemetrytest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/telemetry/test" validationtest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/validation/test" @@ -13,19 +14,21 @@ import ( mediantest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/median/test" ocr2test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ocr2/test" reportingplugintest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/reportingplugin/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) -var MedianProviderServer = medianFactoryServer{ - medianGeneratorConfig: medianGeneratorConfig{ - medianProvider: mediantest.MedianProvider, +func MedianProviderServer(lggr logger.Logger) medianFactoryServer { + return newMedianFactoryServer(lggr, medianGeneratorConfig{ + medianProvider: mediantest.MedianProvider(lggr), pipeline: pipelinetest.PipelineRunner, telemetry: telemetrytest.Telemetry, validationService: validationtest.ValidationService, - }, + }) } const MedianID = "ocr2-reporting-plugin-with-median-provider" @@ -38,7 +41,18 @@ type medianGeneratorConfig struct { } type medianFactoryServer struct { + services.Service medianGeneratorConfig + factory types.ReportingPluginFactory +} + +func newMedianFactoryServer(lggr logger.Logger, cfg medianGeneratorConfig) medianFactoryServer { + lggr = logger.Named(lggr, "medianFactoryServer") + return medianFactoryServer{ + Service: test.NewStaticService(lggr), + medianGeneratorConfig: cfg, + factory: reportingplugintest.Factory(lggr), + } } var _ reportingplugins.ProviderServer[types.MedianProvider] = medianFactoryServer{} @@ -69,23 +83,30 @@ func (s medianFactoryServer) NewReportingPluginFactory(ctx context.Context, conf return nil, fmt.Errorf("failed to evaluate telemetry: %w", err) } - return reportingplugintest.Factory, nil + return s.factory, nil } -var AgnosticProviderServer = agnosticPluginFactoryServer{ - provider: ocr2test.AgnosticPluginProvider, - pipelineRunner: pipelinetest.PipelineRunner, - telemetry: telemetrytest.Telemetry, - validationService: validationtest.ValidationService, +func AgnosticProviderServer(lggr logger.Logger) agnosticPluginFactoryServer { + lggr = logger.Named(lggr, "agnosticPluginFactoryServer") + return agnosticPluginFactoryServer{ + Service: test.NewStaticService(lggr), + provider: ocr2test.AgnosticPluginProvider, + pipelineRunner: pipelinetest.PipelineRunner, + telemetry: telemetrytest.Telemetry, + validationService: validationtest.ValidationService, + factory: reportingplugintest.Factory(lggr), + } } var _ reportingplugins.ProviderServer[types.PluginProvider] = agnosticPluginFactoryServer{} type agnosticPluginFactoryServer struct { + services.Service provider testtypes.PluginProviderTester pipelineRunner testtypes.PipelineEvaluator telemetry testtypes.TelemetryEvaluator validationService testtypes.ValidationEvaluator + factory types.ReportingPluginFactory } func (s agnosticPluginFactoryServer) NewValidationService(ctx context.Context) (core.ValidationService, error) { @@ -114,5 +135,5 @@ func (s agnosticPluginFactoryServer) NewReportingPluginFactory(ctx context.Conte return nil, fmt.Errorf("failed to evaluate telemetry: %w", err) } - return reportingplugintest.Factory, nil + return s.factory, nil } diff --git a/pkg/loop/internal/core/services/reportingplugin/ocr3/reporting_plugin_service.go b/pkg/loop/internal/core/services/reportingplugin/ocr3/reporting_plugin_service.go index 3036af003..620a005cb 100644 --- a/pkg/loop/internal/core/services/reportingplugin/ocr3/reporting_plugin_service.go +++ b/pkg/loop/internal/core/services/reportingplugin/ocr3/reporting_plugin_service.go @@ -238,6 +238,11 @@ func (m reportingPluginServiceServer) NewReportingPluginFactory(ctx context.Cont m.CloseAll(providerRes, errorLogRes, pipelineRunnerRes, telemetryRes, capRegistryRes, relayerSetRes) return nil, err } + //TODO start factory - when to close? + if err = factory.Start(ctx); err != nil { + m.CloseAll(providerRes, errorLogRes, pipelineRunnerRes, telemetryRes, keyValueStoreRes, relayerSetRes) + return nil, err + } id, _, err := m.ServeNew("ReportingPluginProvider", func(s *grpc.Server) { pb.RegisterServiceServer(s, &goplugin.ServiceServer{Srv: factory}) @@ -251,6 +256,7 @@ func (m reportingPluginServiceServer) NewReportingPluginFactory(ctx context.Cont } func RegisterReportingPluginServiceServer(server *grpc.Server, broker net.Broker, brokerCfg net.BrokerConfig, impl core.OCR3ReportingPluginClient) error { + pb.RegisterServiceServer(server, &goplugin.ServiceServer{Srv: impl}) pb.RegisterReportingPluginServiceServer(server, newReportingPluginServiceServer(&net.BrokerExt{Broker: broker, BrokerConfig: brokerCfg}, impl)) return nil } diff --git a/pkg/loop/internal/core/services/reportingplugin/ocr3/test/factory.go b/pkg/loop/internal/core/services/reportingplugin/ocr3/test/factory.go index df93d7812..6bf129191 100644 --- a/pkg/loop/internal/core/services/reportingplugin/ocr3/test/factory.go +++ b/pkg/loop/internal/core/services/reportingplugin/ocr3/test/factory.go @@ -13,34 +13,35 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) -var Factory = ocr3staticPluginFactory{ - ReportingPluginConfig: ocr3reportingPluginConfig, - reportingPlugin: ReportingPlugin, +func Factory(lggr logger.Logger) ocr3StaticPluginFactory { + return newOCR3StatisPluginFactory(lggr, ocr3reportingPluginConfig, ReportingPlugin) } // OCR3 -type ocr3staticPluginFactory struct { +type ocr3StaticPluginFactory struct { + services.Service ocr3types.ReportingPluginConfig reportingPlugin ocr3staticReportingPlugin } -var _ core.OCR3ReportingPluginFactory = (*ocr3staticPluginFactory)(nil) +var _ core.OCR3ReportingPluginFactory = (*ocr3StaticPluginFactory)(nil) -func (o ocr3staticPluginFactory) Name() string { panic("implement me") } - -func (o ocr3staticPluginFactory) Start(ctx context.Context) error { return nil } - -func (o ocr3staticPluginFactory) Close() error { return nil } - -func (o ocr3staticPluginFactory) Ready() error { panic("implement me") } - -func (o ocr3staticPluginFactory) HealthReport() map[string]error { panic("implement me") } +func newOCR3StatisPluginFactory(lggr logger.Logger, cfg ocr3types.ReportingPluginConfig, rp ocr3staticReportingPlugin) ocr3StaticPluginFactory { + return ocr3StaticPluginFactory{ + Service: test.NewStaticService(lggr), + ReportingPluginConfig: cfg, + reportingPlugin: rp, + } +} -func (o ocr3staticPluginFactory) NewReportingPlugin(ctx context.Context, config ocr3types.ReportingPluginConfig) (ocr3types.ReportingPlugin[[]byte], ocr3types.ReportingPluginInfo, error) { +func (o ocr3StaticPluginFactory) NewReportingPlugin(ctx context.Context, config ocr3types.ReportingPluginConfig) (ocr3types.ReportingPlugin[[]byte], ocr3types.ReportingPluginInfo, error) { err := o.equalConfig(config) if err != nil { return nil, ocr3types.ReportingPluginInfo{}, fmt.Errorf("config mismatch: %w", err) @@ -48,7 +49,7 @@ func (o ocr3staticPluginFactory) NewReportingPlugin(ctx context.Context, config return o.reportingPlugin, ocr3rpi, nil } -func (o ocr3staticPluginFactory) equalConfig(other ocr3types.ReportingPluginConfig) error { +func (o ocr3StaticPluginFactory) equalConfig(other ocr3types.ReportingPluginConfig) error { if other.ConfigDigest != o.ConfigDigest { return fmt.Errorf("expected ConfigDigest %x but got %x", o.ConfigDigest, other.ConfigDigest) } @@ -86,7 +87,7 @@ func (o ocr3staticPluginFactory) equalConfig(other ocr3types.ReportingPluginConf } func OCR3ReportingPluginFactory(t *testing.T, factory core.OCR3ReportingPluginFactory) { - expectedFactory := Factory + expectedFactory := Factory(logger.Test(t)) t.Run("OCR3ReportingPluginFactory", func(t *testing.T) { ctx := tests.Context(t) rp, gotRPI, err := factory.NewReportingPlugin(ctx, ocr3reportingPluginConfig) diff --git a/pkg/loop/internal/core/services/reportingplugin/ocr3/test/factory_generators.go b/pkg/loop/internal/core/services/reportingplugin/ocr3/test/factory_generators.go index 657f4cb8c..786fcd638 100644 --- a/pkg/loop/internal/core/services/reportingplugin/ocr3/test/factory_generators.go +++ b/pkg/loop/internal/core/services/reportingplugin/ocr3/test/factory_generators.go @@ -6,24 +6,27 @@ import ( "google.golang.org/grpc" + "github.com/smartcontractkit/chainlink-common/pkg/logger" pipelinetest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/pipeline/test" telemetrytest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/telemetry/test" validationtest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/validation/test" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/net" mediantest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/median/test" ocr2test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ocr2/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) -var MedianServer = medianServer{ - medianGeneratorConfig: medianGeneratorConfig{ - medianProvider: mediantest.MedianProvider, +func MedianServer(lggr logger.Logger) medianServer { + return newMedianServer(lggr, medianGeneratorConfig{ + medianProvider: mediantest.MedianProvider(lggr), pipeline: pipelinetest.PipelineRunner, telemetry: telemetrytest.Telemetry, validationService: validationtest.ValidationService, - }, + }) } const OCR3ReportingPluginWithMedianProviderName = "ocr3-reporting-plugin-with-median-provider" @@ -36,7 +39,18 @@ type medianGeneratorConfig struct { } type medianServer struct { + services.Service medianGeneratorConfig + factory ocr3StaticPluginFactory +} + +func newMedianServer(lggr logger.Logger, cfg medianGeneratorConfig) medianServer { + lggr = logger.Named(lggr, "medianServer") + return medianServer{ + Service: test.NewStaticService(lggr), + medianGeneratorConfig: cfg, + factory: Factory(lggr), + } } func (s medianServer) NewValidationService(ctx context.Context) (core.ValidationService, error) { @@ -65,21 +79,28 @@ func (s medianServer) NewReportingPluginFactory(ctx context.Context, config core return nil, fmt.Errorf("failed to evaluate telemetry: %w", err) } - return Factory, nil + return s.factory, nil } -var AgnosticPluginServer = agnosticPluginServer{ - provider: ocr2test.AgnosticPluginProvider, - pipelineRunner: pipelinetest.PipelineRunner, - telemetry: telemetrytest.Telemetry, - validationService: validationtest.ValidationService, +func AgnosticPluginServer(lggr logger.Logger) agnosticPluginServer { + lggr = logger.Named(lggr, "agnosticPluginServer") + return agnosticPluginServer{ + Service: test.NewStaticService(lggr), + provider: ocr2test.AgnosticPluginProvider, + pipelineRunner: pipelinetest.PipelineRunner, + telemetry: telemetrytest.Telemetry, + validationService: validationtest.ValidationService, + factory: Factory(lggr), + } } type agnosticPluginServer struct { + services.Service provider testtypes.PluginProviderTester pipelineRunner testtypes.PipelineEvaluator telemetry testtypes.TelemetryEvaluator validationService testtypes.ValidationEvaluator + factory ocr3StaticPluginFactory } func (s agnosticPluginServer) NewValidationService(ctx context.Context) (core.ValidationService, error) { @@ -109,5 +130,5 @@ func (s agnosticPluginServer) NewReportingPluginFactory(ctx context.Context, con return nil, fmt.Errorf("failed to evaluate telemetry: %w", err) } - return Factory, nil + return s.factory, nil } diff --git a/pkg/loop/internal/goplugin/plugin_service.go b/pkg/loop/internal/goplugin/plugin_service.go index 5ce50e65d..bcbb37b7a 100644 --- a/pkg/loop/internal/goplugin/plugin_service.go +++ b/pkg/loop/internal/goplugin/plugin_service.go @@ -43,21 +43,30 @@ type PluginService[P grpcPlugin, S services.Service] struct { client *plugin.Client clientProtocol plugin.ClientProtocol - newService func(context.Context, any) (S, error) + newService func(context.Context, any) (S, services.HealthReporter, error) serviceCh chan struct{} // closed when service is available Service S + Health services.HealthReporter //TODO may or may not be the same as Service? testInterrupt chan func(*PluginService[P, S]) // tests only (via TestHook) to enable access to internals without racing } -func (s *PluginService[P, S]) Init(pluginName string, p P, newService func(context.Context, any) (S, error), - lggr logger.Logger, cmd func() *exec.Cmd, stopCh chan struct{}) { +type NewService[S any] func(context.Context, any) (S, services.HealthReporter, error) + +func (s *PluginService[P, S]) Init( + pluginName string, + grpcPlug P, + newService NewService[S], + lggr logger.Logger, + cmd func() *exec.Cmd, + stopCh chan struct{}, +) { s.pluginName = pluginName s.lggr = lggr s.cmd = cmd s.stopCh = stopCh - s.grpcPlug = p + s.grpcPlug = grpcPlug s.newService = newService s.serviceCh = make(chan struct{}) } @@ -142,7 +151,7 @@ func (s *PluginService[P, S]) launch() (*plugin.Client, plugin.ClientProtocol, e case <-s.serviceCh: // s.service already set default: - s.Service, err = s.newService(ctx, i) + s.Service, s.Health, err = s.newService(ctx, i) if err != nil { abort() return nil, nil, fmt.Errorf("failed to create service: %w", err) @@ -175,7 +184,8 @@ func (s *PluginService[P, S]) HealthReport() map[string]error { select { case <-s.serviceCh: hr := map[string]error{s.Name(): s.Healthy()} - services.CopyHealth(hr, s.Service.HealthReport()) + fmt.Println("------------------GOT THE HEALTH") + services.CopyHealth(hr, s.Health.HealthReport()) //TODO is this called or not? return hr default: return map[string]error{s.Name(): ErrPluginUnavailable} @@ -189,7 +199,7 @@ func (s *PluginService[P, S]) Close() error { select { case <-s.serviceCh: - if cerr := s.Service.Close(); !errors.Is(cerr, context.Canceled) && status.Code(cerr) != codes.Canceled { + if cerr := s.Service.Close(); !isCanceled(cerr) { err = errors.Join(err, cerr) } default: @@ -201,7 +211,7 @@ func (s *PluginService[P, S]) Close() error { func (s *PluginService[P, S]) closeClient() (err error) { if s.clientProtocol != nil { - if cerr := s.clientProtocol.Close(); !errors.Is(cerr, context.Canceled) { + if cerr := s.clientProtocol.Close(); !isCanceled(cerr) { err = cerr } } @@ -253,3 +263,7 @@ func (ch TestPluginService[P, S]) Reset() { } <-done } + +func isCanceled(err error) bool { + return errors.Is(err, context.Canceled) || status.Code(err) == codes.Canceled +} diff --git a/pkg/loop/internal/goplugin/service.go b/pkg/loop/internal/goplugin/service.go index d89d60668..10deb425e 100644 --- a/pkg/loop/internal/goplugin/service.go +++ b/pkg/loop/internal/goplugin/service.go @@ -62,11 +62,12 @@ func (s *ServiceClient) HealthReport() map[string]error { ctx, cancel = context.WithTimeout(ctx, time.Second) defer cancel() + name := s.b.Logger.Name() reply, err := s.grpc.HealthReport(ctx, &emptypb.Empty{}) if err != nil { - return map[string]error{s.b.Logger.Name(): err} + return map[string]error{name: err} } - hr := healthReport(reply.HealthReport) + hr := healthReport(name, reply.HealthReport) hr[s.b.Logger.Name()] = nil return hr } @@ -102,14 +103,14 @@ func (s *ServiceServer) HealthReport(ctx context.Context, empty *emptypb.Empty) return &r, nil } -func healthReport(s map[string]string) (hr map[string]error) { +func healthReport(prefix string, s map[string]string) (hr map[string]error) { hr = make(map[string]error, len(s)) for n, e := range s { var err error if e != "" { err = errors.New(e) } - hr[n] = err + hr[prefix+"."+n] = err } return hr } diff --git a/pkg/loop/internal/relayer/pluginprovider/contractreader/test/contract_reader.go b/pkg/loop/internal/relayer/pluginprovider/contractreader/test/contract_reader.go index 0551cbc87..e7b50066b 100644 --- a/pkg/loop/internal/relayer/pluginprovider/contractreader/test/contract_reader.go +++ b/pkg/loop/internal/relayer/pluginprovider/contractreader/test/contract_reader.go @@ -37,16 +37,6 @@ type staticContractReader struct { var _ testtypes.Evaluator[types.ContractReader] = staticContractReader{} var _ types.ContractReader = staticContractReader{} -func (c staticContractReader) Start(_ context.Context) error { return nil } - -func (c staticContractReader) Close() error { return nil } - -func (c staticContractReader) Ready() error { panic("unimplemented") } - -func (c staticContractReader) Name() string { panic("unimplemented") } - -func (c staticContractReader) HealthReport() map[string]error { panic("unimplemented") } - func (c staticContractReader) Bind(_ context.Context, _ []types.BoundContract) error { return nil } diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_factory_server.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_factory_server.go index 265e31627..cd2c8d9f5 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_factory_server.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_factory_server.go @@ -8,15 +8,18 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" reportingplugintest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/reportingplugin/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) -var CommitFactoryServer = commitFactoryServer{ - commitFactoryServerConfig: commitFactoryServerConfig{ - provider: CommitProvider, - }, +func CommitFactoryServer(lggr logger.Logger) commitFactoryServer { + return newCommitFactoryServer(lggr, commitFactoryServerConfig{ + provider: CommitProvider(lggr), + }) } type commitFactoryServerConfig struct { @@ -26,7 +29,18 @@ type commitFactoryServerConfig struct { var _ types.CCIPCommitFactoryGenerator = commitFactoryServer{} type commitFactoryServer struct { + services.Service commitFactoryServerConfig + factory types.ReportingPluginFactory +} + +func newCommitFactoryServer(lggr logger.Logger, cfg commitFactoryServerConfig) commitFactoryServer { + lggr = logger.Named(lggr, "commitFactoryServer") + return commitFactoryServer{ + Service: test.NewStaticService(lggr), + commitFactoryServerConfig: cfg, + factory: reportingplugintest.Factory(lggr), + } } // NewCommitFactory implements types.CCIPCommitFactoryGenerator. @@ -35,11 +49,11 @@ func (e commitFactoryServer) NewCommitFactory(ctx context.Context, provider type if err != nil { return nil, err } - return reportingplugintest.Factory, nil + return e.factory, nil } func RunCommitLOOP(t *testing.T, p types.CCIPCommitFactoryGenerator) { - CommitLOOPTester{CommitProvider}.Run(t, p) + CommitLOOPTester{CommitProvider(logger.Test(t))}.Run(t, p) } type CommitLOOPTester struct { @@ -75,7 +89,7 @@ func runCommitReportingPluginFactory(t *testing.T, factory types.ReportingPlugin // that wraps the static implementation var expectedReportingPlugin = reportingplugintest.ReportingPlugin - rp, gotRPI, err := factory.NewReportingPlugin(ctx, reportingplugintest.Factory.ReportingPluginConfig) + rp, gotRPI, err := factory.NewReportingPlugin(ctx, reportingplugintest.StaticFactoryConfig.ReportingPluginConfig) require.NoError(t, err) assert.Equal(t, rpi, gotRPI) t.Cleanup(func() { assert.NoError(t, rp.Close()) }) diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_provider.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_provider.go index 83d0057f5..ead428350 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_provider.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_provider.go @@ -9,8 +9,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" ocr2test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ocr2/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" ) @@ -28,19 +31,19 @@ type CommitProviderTester interface { // CommitProvider is a static implementation of the CommitProviderTester interface. // It is to be used in tests the verify grpc implementations of the CommitProvider interface. -var CommitProvider = staticCommitProvider{ - staticCommitProviderConfig: staticCommitProviderConfig{ +func CommitProvider(lggr logger.Logger) staticCommitProvider { + return newStaticCommitProvider(lggr, staticCommitProviderConfig{ addr: ccip.Address("some address"), offchainDigester: ocr2test.OffchainConfigDigester, contractTracker: ocr2test.ContractConfigTracker, contractTransmitter: ocr2test.ContractTransmitter, - commitStoreReader: CommitStoreReader, + commitStoreReader: CommitStoreReader(lggr), offRampReader: OffRampReader, onRampReader: OnRampReader, priceGetter: PriceGetter, priceRegistryReader: PriceRegistryReader, sourceNativeTokenResponse: ccip.Address("source native token response"), - }, + }) } var _ CommitProviderTester = staticCommitProvider{} @@ -60,16 +63,20 @@ type staticCommitProviderConfig struct { } type staticCommitProvider struct { + services.Service staticCommitProviderConfig } -// ContractReader implements CommitProviderEvaluator. -func (s staticCommitProvider) ContractReader() types.ContractReader { - return nil +func newStaticCommitProvider(lggr logger.Logger, cfg staticCommitProviderConfig) staticCommitProvider { + lggr = logger.Named(lggr, "staticCommitProvider") + return staticCommitProvider{ + Service: test.NewStaticService(lggr), + staticCommitProviderConfig: cfg, + } } -// Close implements CommitProviderEvaluator. -func (s staticCommitProvider) Close() error { +// ContractReader implements CommitProviderEvaluator. +func (s staticCommitProvider) ContractReader() types.ContractReader { return nil } @@ -151,16 +158,6 @@ func (s staticCommitProvider) Evaluate(ctx context.Context, other types.CCIPComm return nil } -// HealthReport implements CommitProviderEvaluator. -func (s staticCommitProvider) HealthReport() map[string]error { - panic("unimplemented") -} - -// Name implements CommitProviderEvaluator. -func (s staticCommitProvider) Name() string { - panic("unimplemented") -} - // NewCommitStoreReader implements CommitProviderEvaluator. func (s staticCommitProvider) NewCommitStoreReader(ctx context.Context, addr ccip.Address) (ccip.CommitStoreReader, error) { return s.commitStoreReader, nil @@ -191,21 +188,11 @@ func (s staticCommitProvider) OffchainConfigDigester() libocr.OffchainConfigDige return s.offchainDigester } -// Ready implements CommitProviderEvaluator. -func (s staticCommitProvider) Ready() error { - return nil -} - // SourceNativeToken implements CommitProviderEvaluator. func (s staticCommitProvider) SourceNativeToken(ctx context.Context, addr ccip.Address) (ccip.Address, error) { return s.sourceNativeTokenResponse, nil } -// Start implements CommitProviderEvaluator. -func (s staticCommitProvider) Start(context.Context) error { - return nil -} - // AssertEqual implements CommitProviderTester. func (s staticCommitProvider) AssertEqual(ctx context.Context, t *testing.T, other types.CCIPCommitProvider) { t.Run("StaticCommitProvider", func(t *testing.T) { diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_provider_test.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_provider_test.go index 1559b5bd0..036c120e3 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_provider_test.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_provider_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc" + "github.com/smartcontractkit/chainlink-common/pkg/logger" loopnet "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/net" ccippb "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb/ccip" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/ccip" @@ -20,21 +21,23 @@ func TestStaticCommitProvider(t *testing.T) { t.Run("Self consistent Evaluate", func(t *testing.T) { t.Parallel() ctx := tests.Context(t) + lggr := logger.Test(t) // static test implementation is self consistent - assert.NoError(t, CommitProvider.Evaluate(ctx, CommitProvider)) + assert.NoError(t, CommitProvider(lggr).Evaluate(ctx, CommitProvider(lggr))) // error when the test implementation evaluates something that differs from form itself - botched := CommitProvider + botched := CommitProvider(lggr) botched.priceRegistryReader = staticPriceRegistryReader{} - err := CommitProvider.Evaluate(ctx, botched) + err := CommitProvider(lggr).Evaluate(ctx, botched) require.Error(t, err) var evalErr evaluationError require.True(t, errors.As(err, &evalErr), "expected error to be an evaluationError") assert.Equal(t, priceRegistryComponent, evalErr.component) }) t.Run("Self consistent AssertEqual", func(t *testing.T) { + lggr := logger.Test(t) // no parallel because the AssertEqual is parallel - CommitProvider.AssertEqual(tests.Context(t), t, CommitProvider) + CommitProvider(lggr).AssertEqual(tests.Context(t), t, CommitProvider(lggr)) }) } @@ -84,7 +87,7 @@ func roundTripCommitProviderTests(t *testing.T, client types.CCIPCommitProvider) } func setupCommitProviderServer(t *testing.T, s *grpc.Server, b *loopnet.BrokerExt) *ccip.CommitProviderServer { - commitProvider := ccip.NewCommitProviderServer(CommitProvider, b) + commitProvider := ccip.NewCommitProviderServer(CommitProvider(logger.Test(t)), b) ccippb.RegisterCommitCustomHandlersServer(s, commitProvider) return commitProvider } diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_store.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_store.go index 0d5e3d75c..9e20cd3b9 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_store.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_store.go @@ -8,13 +8,16 @@ import ( "reflect" "time" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" ) // CommitStoreReader is a test implementation of the CommitStoreReader interface -var CommitStoreReader = staticCommitStoreReader{ - staticCommitStoreReaderConfig: staticCommitStoreReaderConfig{ +func CommitStoreReader(lggr logger.Logger) staticCommitStoreReader { + return newStaticCommitStoreReader(lggr, staticCommitStoreReaderConfig{ // change config test data changeConfigRequest: changeConfigRequest{ onchainConfig: []byte("onchainConfig"), @@ -242,7 +245,7 @@ var CommitStoreReader = staticCommitStoreReader{ }, ProofFlagBits: big.NewInt(1), }, - }, + }) } type CommitStoreReaderEvaluator interface { @@ -251,9 +254,18 @@ type CommitStoreReaderEvaluator interface { } type staticCommitStoreReader struct { + services.Service staticCommitStoreReaderConfig } +func newStaticCommitStoreReader(lggr logger.Logger, cfg staticCommitStoreReaderConfig) staticCommitStoreReader { + lggr = logger.Named(lggr, "staticCommitStoreReader") + return staticCommitStoreReader{ + Service: test.NewStaticService(lggr), + staticCommitStoreReaderConfig: cfg, + } +} + // ChangeConfig implements CommitStoreReaderEvaluator. func (s staticCommitStoreReader) ChangeConfig(ctx context.Context, onchainConfig []byte, offchainConfig []byte) (ccip.Address, error) { if !bytes.Equal(onchainConfig, s.changeConfigRequest.onchainConfig) { diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_store_test.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_store_test.go index 246be2d75..f50e15e05 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_store_test.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/commit_store_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc" + "github.com/smartcontractkit/chainlink-common/pkg/logger" loopnet "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/net" ccippb "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb/ccip" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/ccip" @@ -22,12 +23,13 @@ func TestStaticCommitStore(t *testing.T) { // static test implementation is self consistent ctx := context.Background() - assert.NoError(t, CommitStoreReader.Evaluate(ctx, CommitStoreReader)) + csr := CommitStoreReader(logger.Test(t)) + assert.NoError(t, csr.Evaluate(ctx, csr)) // error when the test implementation is evaluates something that differs from the static implementation - botched := CommitStoreReader + botched := CommitStoreReader(logger.Test(t)) botched.changeConfigResponse = "not the right conifg" - err := CommitStoreReader.Evaluate(ctx, botched) + err := csr.Evaluate(ctx, botched) require.Error(t, err) assert.Contains(t, err.Error(), "not the right conifg") } @@ -52,24 +54,27 @@ func TestCommitStoreGRPC(t *testing.T) { // do not add client.Close to this test, test that from the driver test func roundTripCommitStoreTests(t *testing.T, client cciptypes.CommitStoreReader) { t.Run("ChangeConfig", func(t *testing.T) { - gotAddr, err := client.ChangeConfig(tests.Context(t), CommitStoreReader.changeConfigRequest.onchainConfig, CommitStoreReader.changeConfigRequest.offchainConfig) + csr := CommitStoreReader(logger.Test(t)) + gotAddr, err := client.ChangeConfig(tests.Context(t), csr.changeConfigRequest.onchainConfig, csr.changeConfigRequest.offchainConfig) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.changeConfigResponse, gotAddr) + assert.Equal(t, csr.changeConfigResponse, gotAddr) }) t.Run("DecodeCommitReport", func(t *testing.T) { - report, err := client.DecodeCommitReport(tests.Context(t), CommitStoreReader.decodeCommitReportRequest) + csr := CommitStoreReader(logger.Test(t)) + report, err := client.DecodeCommitReport(tests.Context(t), csr.decodeCommitReportRequest) require.NoError(t, err) - if !reflect.DeepEqual(CommitStoreReader.decodeCommitReportResponse, report) { - t.Errorf("expected %v, got %v", CommitStoreReader.decodeCommitReportResponse, report) + if !reflect.DeepEqual(csr.decodeCommitReportResponse, report) { + t.Errorf("expected %v, got %v", csr.decodeCommitReportResponse, report) } }) // reuse the test data for the encode method t.Run("EncodeCommtReport", func(t *testing.T) { - report, err := client.EncodeCommitReport(tests.Context(t), CommitStoreReader.decodeCommitReportResponse) + csr := CommitStoreReader(logger.Test(t)) + report, err := client.EncodeCommitReport(tests.Context(t), csr.decodeCommitReportResponse) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.decodeCommitReportRequest, report) + assert.Equal(t, csr.decodeCommitReportRequest, report) }) // exercise all the gas price estimator methods @@ -106,78 +111,82 @@ func roundTripCommitStoreTests(t *testing.T, client cciptypes.CommitStoreReader) }) t.Run("GetAcceptedCommitReportGteTimestamp", func(t *testing.T) { + csr := CommitStoreReader(logger.Test(t)) report, err := client.GetAcceptedCommitReportsGteTimestamp(tests.Context(t), - CommitStoreReader.getAcceptedCommitReportsGteTimestampRequest.timestamp, - CommitStoreReader.getAcceptedCommitReportsGteTimestampRequest.confirmations) + csr.getAcceptedCommitReportsGteTimestampRequest.timestamp, + csr.getAcceptedCommitReportsGteTimestampRequest.confirmations) require.NoError(t, err) - if !reflect.DeepEqual(CommitStoreReader.getAcceptedCommitReportsGteTimestampResponse, report) { - t.Errorf("expected %v, got %v", CommitStoreReader.getAcceptedCommitReportsGteTimestampResponse, report) + if !reflect.DeepEqual(csr.getAcceptedCommitReportsGteTimestampResponse, report) { + t.Errorf("expected %v, got %v", csr.getAcceptedCommitReportsGteTimestampResponse, report) } }) t.Run("GetCommitReportMatchingSeqNum", func(t *testing.T) { + csr := CommitStoreReader(logger.Test(t)) report, err := client.GetCommitReportMatchingSeqNum(tests.Context(t), - CommitStoreReader.getCommitReportMatchingSeqNumRequest.seqNum, - CommitStoreReader.getCommitReportMatchingSeqNumRequest.confirmations) + csr.getCommitReportMatchingSeqNumRequest.seqNum, + csr.getCommitReportMatchingSeqNumRequest.confirmations) require.NoError(t, err) // use the same response as the reportsGteTimestamp for simplicity - if !reflect.DeepEqual(CommitStoreReader.getAcceptedCommitReportsGteTimestampResponse, report) { - t.Errorf("expected %v, got %v", CommitStoreReader.getAcceptedCommitReportsGteTimestampRequest, report) + if !reflect.DeepEqual(csr.getAcceptedCommitReportsGteTimestampResponse, report) { + t.Errorf("expected %v, got %v", csr.getAcceptedCommitReportsGteTimestampRequest, report) } }) t.Run("GetCommitStoreStaticConfig", func(t *testing.T) { config, err := client.GetCommitStoreStaticConfig(tests.Context(t)) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.getCommitStoreStaticConfigResponse, config) + assert.Equal(t, CommitStoreReader(logger.Test(t)).getCommitStoreStaticConfigResponse, config) }) t.Run("GetExpectedNextSequenceNumber", func(t *testing.T) { seq, err := client.GetExpectedNextSequenceNumber(tests.Context(t)) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.getExpectedNextSequenceNumberResponse, seq) + assert.Equal(t, CommitStoreReader(logger.Test(t)).getExpectedNextSequenceNumberResponse, seq) }) t.Run("GetLatestPriceEpochAndRound", func(t *testing.T) { got, err := client.GetLatestPriceEpochAndRound(tests.Context(t)) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.getLatestPriceEpochAndRoundResponse, got) + assert.Equal(t, CommitStoreReader(logger.Test(t)).getLatestPriceEpochAndRoundResponse, got) }) t.Run("IsBlessed", func(t *testing.T) { - got, err := client.IsBlessed(tests.Context(t), CommitStoreReader.isBlessedRequest) + csr := CommitStoreReader(logger.Test(t)) + got, err := client.IsBlessed(tests.Context(t), csr.isBlessedRequest) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.isBlessedResponse, got) + assert.Equal(t, csr.isBlessedResponse, got) }) t.Run("IsDestChainHealthy", func(t *testing.T) { got, err := client.IsDestChainHealthy(tests.Context(t)) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.isDestChainHealthyResponse, got) + assert.Equal(t, CommitStoreReader(logger.Test(t)).isDestChainHealthyResponse, got) }) t.Run("IsDown", func(t *testing.T) { got, err := client.IsDown(tests.Context(t)) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.isDownResponse, got) + assert.Equal(t, CommitStoreReader(logger.Test(t)).isDownResponse, got) }) t.Run("OffchainConfig", func(t *testing.T) { config, err := client.OffchainConfig(tests.Context(t)) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.offchainConfigResponse, config) + assert.Equal(t, CommitStoreReader(logger.Test(t)).offchainConfigResponse, config) }) t.Run("VerifyExecutionReport", func(t *testing.T) { - got, err := client.VerifyExecutionReport(tests.Context(t), CommitStoreReader.verifyExecutionReportRequest) + csr := CommitStoreReader(logger.Test(t)) + got, err := client.VerifyExecutionReport(tests.Context(t), csr.verifyExecutionReportRequest) require.NoError(t, err) - assert.Equal(t, CommitStoreReader.verifyExecutionReportResponse, got) + assert.Equal(t, csr.verifyExecutionReportResponse, got) }) } func setupCommitStoreServer(t *testing.T, s *grpc.Server, b *loopnet.BrokerExt) *ccip.CommitStoreGRPCServer { ctx := tests.Context(t) - commitProvider, err := ccip.NewCommitStoreReaderGRPCServer(ctx, CommitStoreReader, b) + commitProvider, err := ccip.NewCommitStoreReaderGRPCServer(ctx, CommitStoreReader(logger.Test(t)), b) require.NoError(t, err) ccippb.RegisterCommitStoreReaderServer(s, commitProvider) return commitProvider diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_factory_server.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_factory_server.go index 4c748d82a..c3c943851 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_factory_server.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_factory_server.go @@ -8,15 +8,18 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" reportingplugintest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/reportingplugin/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) -var ExecFactoryServer = execFactoryServer{ - execFactoryServerConfig: execFactoryServerConfig{ - provider: ExecutionProvider, - }, +func ExecFactoryServer(lggr logger.Logger) execFactoryServer { + return newExecFactoryServer(lggr, execFactoryServerConfig{ + provider: ExecutionProvider(lggr), + }) } type execFactoryServerConfig struct { @@ -26,7 +29,18 @@ type execFactoryServerConfig struct { var _ types.CCIPExecutionFactoryGenerator = execFactoryServer{} type execFactoryServer struct { + services.Service execFactoryServerConfig + factory types.ReportingPluginFactory +} + +func newExecFactoryServer(lggr logger.Logger, cfg execFactoryServerConfig) execFactoryServer { + lggr = logger.Named(lggr, "execFactoryServer") + return execFactoryServer{ + Service: test.NewStaticService(lggr), + execFactoryServerConfig: cfg, + factory: reportingplugintest.Factory(lggr), + } } // NewExecutionFactory implements types.CCIPExecFactoryGenerator. @@ -40,11 +54,12 @@ func (e execFactoryServer) NewExecutionFactory(ctx context.Context, srcProvider if err2 != nil { return nil, err2 } - return reportingplugintest.Factory, nil + return e.factory, nil } func RunExecutionLOOP(t *testing.T, p types.CCIPExecutionFactoryGenerator) { - ExecutionLOOPTester{SrcProvider: ExecutionProvider, DstProvider: ExecutionProvider, SrcChainID: 0, DstChainID: 0}.Run(t, p) + lggr := logger.Test(t) + ExecutionLOOPTester{SrcProvider: ExecutionProvider(lggr), DstProvider: ExecutionProvider(lggr), SrcChainID: 0, DstChainID: 0}.Run(t, p) } type ExecutionLOOPTester struct { @@ -83,7 +98,7 @@ func runExecReportingPluginFactory(t *testing.T, factory types.ReportingPluginFa // that wraps the static implementation var expectedReportingPlugin = reportingplugintest.ReportingPlugin - rp, gotRPI, err := factory.NewReportingPlugin(tests.Context(t), reportingplugintest.Factory.ReportingPluginConfig) + rp, gotRPI, err := factory.NewReportingPlugin(tests.Context(t), reportingplugintest.StaticFactoryConfig.ReportingPluginConfig) require.NoError(t, err) assert.Equal(t, rpi, gotRPI) t.Cleanup(func() { assert.NoError(t, rp.Close()) }) diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_provider.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_provider.go index 2dec5de1e..5143cdc5f 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_provider.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_provider.go @@ -9,8 +9,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/logger" ocr2test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ocr2/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" ) @@ -28,13 +31,13 @@ type ExecProviderTester interface { // ExecutionProvider is a static implementation of the ExecProviderTester interface. // It is to be used in tests the verify grpc implementations of the ExecProvider interface. -var ExecutionProvider = staticExecProvider{ - staticExecProviderConfig: staticExecProviderConfig{ +func ExecutionProvider(lggr logger.Logger) staticExecProvider { + return newStaticExecProvider(lggr, staticExecProviderConfig{ addr: ccip.Address("some address"), offchainDigester: ocr2test.OffchainConfigDigester, contractTracker: ocr2test.ContractConfigTracker, contractTransmitter: ocr2test.ContractTransmitter, - commitStoreReader: CommitStoreReader, + commitStoreReader: CommitStoreReader(lggr), offRampReader: OffRampReader, onRampReader: OnRampReader, priceRegistryReader: PriceRegistryReader, @@ -42,7 +45,7 @@ var ExecutionProvider = staticExecProvider{ tokenDataReader: TokenDataReader, tokenPoolBatchedReader: TokenPoolBatchedReader, transactionStatusResponse: types.Fatal, - }, + }) } var _ ExecProviderTester = staticExecProvider{} @@ -64,16 +67,20 @@ type staticExecProviderConfig struct { } type staticExecProvider struct { + services.Service staticExecProviderConfig } -// ContractReader implements ExecProviderEvaluator. -func (s staticExecProvider) ContractReader() types.ContractReader { - return nil +func newStaticExecProvider(lggr logger.Logger, cfg staticExecProviderConfig) staticExecProvider { + lggr = logger.Named(lggr, "staticExecProvider") + return staticExecProvider{ + Service: test.NewStaticService(lggr), + staticExecProviderConfig: cfg, + } } -// Close implements ExecProviderEvaluator. -func (s staticExecProvider) Close() error { +// ContractReader implements ExecProviderEvaluator. +func (s staticExecProvider) ContractReader() types.ContractReader { return nil } @@ -174,16 +181,6 @@ func (s staticExecProvider) Evaluate(ctx context.Context, other types.CCIPExecPr return nil } -// HealthReport implements ExecProviderEvaluator. -func (s staticExecProvider) HealthReport() map[string]error { - panic("unimplemented") -} - -// Name implements ExecProviderEvaluator. -func (s staticExecProvider) Name() string { - panic("unimplemented") -} - // GetTransactionStatus implements ExecProviderEvaluator. func (s staticExecProvider) GetTransactionStatus(ctx context.Context, tid string) (types.TransactionStatus, error) { return s.transactionStatusResponse, nil @@ -224,21 +221,11 @@ func (s staticExecProvider) OffchainConfigDigester() libocr.OffchainConfigDigest return s.offchainDigester } -// Ready implements ExecProviderEvaluator. -func (s staticExecProvider) Ready() error { - return nil -} - // SourceNativeToken implements ExecProviderEvaluator. func (s staticExecProvider) SourceNativeToken(ctx context.Context, addr ccip.Address) (ccip.Address, error) { return s.sourceNativeTokenResponse, nil } -// Start implements ExecProviderEvaluator. -func (s staticExecProvider) Start(context.Context) error { - return nil -} - // AssertEqual implements ExecProviderTester. func (s staticExecProvider) AssertEqual(ctx context.Context, t *testing.T, other types.CCIPExecProvider) { t.Run("StaticExecProvider", func(t *testing.T) { diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_provider_test.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_provider_test.go index 9d898dbfc..33b3ef61f 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_provider_test.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test/exec_provider_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc" + "github.com/smartcontractkit/chainlink-common/pkg/logger" loopnet "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/net" ccippb "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb/ccip" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/ccip" @@ -20,21 +21,23 @@ func TestStaticExecProvider(t *testing.T) { ctx := tests.Context(t) t.Run("Self consistent Evaluate", func(t *testing.T) { t.Parallel() + ep := ExecutionProvider(logger.Test(t)) // static test implementation is self consistent - assert.NoError(t, ExecutionProvider.Evaluate(ctx, ExecutionProvider)) + assert.NoError(t, ep.Evaluate(ctx, ep)) // error when the test implementation evaluates something that differs from form itself - botched := ExecutionProvider + botched := ExecutionProvider(logger.Test(t)) botched.priceRegistryReader = staticPriceRegistryReader{} - err := ExecutionProvider.Evaluate(ctx, botched) + err := ep.Evaluate(ctx, botched) require.Error(t, err) var evalErr evaluationError require.True(t, errors.As(err, &evalErr), "expected error to be an evaluationError") assert.Equal(t, priceRegistryComponent, evalErr.component) }) t.Run("Self consistent AssertEqual", func(t *testing.T) { + ep := ExecutionProvider(logger.Test(t)) // no parallel because the AssertEqual is parallel - ExecutionProvider.AssertEqual(ctx, t, ExecutionProvider) + ep.AssertEqual(ctx, t, ep) }) } @@ -92,18 +95,18 @@ func roundTripExecProviderTests(t *testing.T, client types.CCIPExecProvider) { t.Run("SourceNativeToken", func(t *testing.T) { token, err := client.SourceNativeToken(tests.Context(t), "ignored") require.NoError(t, err) - assert.Equal(t, ExecutionProvider.sourceNativeTokenResponse, token) + assert.Equal(t, ExecutionProvider(logger.Test(t)).sourceNativeTokenResponse, token) }) t.Run("GetTransactionStatus", func(t *testing.T) { status, err := client.GetTransactionStatus(tests.Context(t), "ignored") require.NoError(t, err) - assert.Equal(t, ExecutionProvider.transactionStatusResponse, status) + assert.Equal(t, ExecutionProvider(logger.Test(t)).transactionStatusResponse, status) }) } func setupExecProviderServer(t *testing.T, server *grpc.Server, b *loopnet.BrokerExt) *ccip.ExecProviderServer { - execProvider := ccip.NewExecProviderServer(ExecutionProvider, b) + execProvider := ccip.NewExecProviderServer(ExecutionProvider(logger.Test(t)), b) ccippb.RegisterExecutionCustomHandlersServer(server, execProvider) return execProvider } diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/median/test/median.go b/pkg/loop/internal/relayer/pluginprovider/ext/median/test/median.go index 2c210d564..fa4079627 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/median/test/median.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/median/test/median.go @@ -16,16 +16,20 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" libocr "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" errorlogtest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/errorlog/test" reportingplugintest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/reportingplugin/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) func PluginMedian(t *testing.T, p core.PluginMedian) { - PluginMedianTest{&MedianProvider}.TestPluginMedian(t, p) + PluginMedianTest{MedianProvider(logger.Test(t))}.TestPluginMedian(t, p) } type PluginMedianTest struct { @@ -39,6 +43,11 @@ func (m PluginMedianTest) TestPluginMedian(t *testing.T, p core.PluginMedian) { require.NoError(t, err) ReportingPluginFactory(t, factory) + servicetest.AssertHealthReportNames(t, p.HealthReport(), + "PluginMedianClient", + "PluginMedianClient.staticMedianFactoryServer", + "PluginMedianClient.staticMedianFactoryServer.staticReportingPluginFactory", + ) }) // when gasPriceSubunitsDataSource is meant to trigger a no-op @@ -48,6 +57,11 @@ func (m PluginMedianTest) TestPluginMedian(t *testing.T, p core.PluginMedian) { require.NoError(t, err) ReportingPluginFactory(t, factory) + servicetest.AssertHealthReportNames(t, p.HealthReport(), + "PluginMedianClient", + "PluginMedianClient.staticMedianFactoryServer", + "PluginMedianClient.staticMedianFactoryServer.staticReportingPluginFactory", + ) }) } @@ -80,11 +94,28 @@ type staticPluginMedianConfig struct { } type staticMedianFactoryServer struct { + services.Service staticPluginMedianConfig + reportingPluginFactory staticReportingPluginFactory +} + +func newStaticMedianFactoryServer(lggr logger.Logger, cfg staticPluginMedianConfig) staticMedianFactoryServer { + lggr = logger.Named(lggr, "staticMedianFactoryServer") + return staticMedianFactoryServer{ + Service: test.NewStaticService(lggr), + staticPluginMedianConfig: cfg, + reportingPluginFactory: newStaticReportingPluginFactory(lggr, reportingPluginConfig), + } } var _ core.PluginMedian = staticMedianFactoryServer{} +func (s staticMedianFactoryServer) HealthReport() map[string]error { + hp := s.Service.HealthReport() + services.CopyHealth(hp, s.reportingPluginFactory.HealthReport()) + return hp +} + func (s staticMedianFactoryServer) NewMedianFactory(ctx context.Context, provider types.MedianProvider, contractID string, dataSource, juelsPerFeeCoinDataSource, gasPriceSubunitsDataSource median.DataSource, errorLog core.ErrorLog) (types.ReportingPluginFactory, error) { // the provider may be a grpc client, so we can't compare it directly // but in all of these static tests, the implementation of the provider is expected @@ -123,25 +154,22 @@ func (s staticMedianFactoryServer) NewMedianFactory(ctx context.Context, provide if err := errorLog.SaveError(ctx, "an error"); err != nil { return nil, fmt.Errorf("failed to save error: %w", err) } - return staticReportingPluginFactory{ReportingPluginConfig: reportingPluginConfig}, nil + return s.reportingPluginFactory, nil } type staticReportingPluginFactory struct { + services.Service libocr.ReportingPluginConfig } -func (s staticReportingPluginFactory) Name() string { return "staticReportingPluginFactory" } - -func (s staticReportingPluginFactory) Start(ctx context.Context) error { - return nil +func newStaticReportingPluginFactory(lggr logger.Logger, cfg libocr.ReportingPluginConfig) staticReportingPluginFactory { + lggr = logger.Named(lggr, "staticReportingPluginFactory") + return staticReportingPluginFactory{ + Service: test.NewStaticService(lggr), + ReportingPluginConfig: cfg, + } } -func (s staticReportingPluginFactory) Close() error { return nil } - -func (s staticReportingPluginFactory) Ready() error { panic("implement me") } - -func (s staticReportingPluginFactory) HealthReport() map[string]error { panic("implement me") } - func (s staticReportingPluginFactory) NewReportingPlugin(ctx context.Context, config libocr.ReportingPluginConfig) (libocr.ReportingPlugin, libocr.ReportingPluginInfo, error) { if config.ConfigDigest != s.ConfigDigest { return nil, libocr.ReportingPluginInfo{}, fmt.Errorf("expected ConfigDigest %x but got %x", s.ConfigDigest, config.ConfigDigest) @@ -199,20 +227,19 @@ type staticMedianProviderConfig struct { // implements types.MedianProvider and testtypes.Evaluator[types.MedianProvider] type staticMedianProvider struct { + services.Service staticMedianProviderConfig } -var _ testtypes.MedianProviderTester = staticMedianProvider{} - -func (s staticMedianProvider) Start(ctx context.Context) error { return nil } - -func (s staticMedianProvider) Close() error { return nil } - -func (s staticMedianProvider) Ready() error { panic("unimplemented") } - -func (s staticMedianProvider) Name() string { panic("unimplemented") } +func newStaticMedianProvider(lggr logger.Logger, cfg staticMedianProviderConfig) staticMedianProvider { + lggr = logger.Named(lggr, "staticMedianProvider") + return staticMedianProvider{ + Service: test.NewStaticService(lggr), + staticMedianProviderConfig: cfg, + } +} -func (s staticMedianProvider) HealthReport() map[string]error { panic("unimplemented") } +var _ testtypes.MedianProviderTester = staticMedianProvider{} func (s staticMedianProvider) OffchainConfigDigester() libocr.OffchainConfigDigester { return s.offchainDigester diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/median/test/test.go b/pkg/loop/internal/relayer/pluginprovider/ext/median/test/test.go index ef704643d..b86f95bde 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/median/test/test.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/median/test/test.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" libocr "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" errorlogtest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/errorlog/test" chaincomponentstest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/contractreader/test" ocr2test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ocr2/test" @@ -23,41 +24,39 @@ const ( n = 12 ) -var ( - MedianFactoryServer = staticMedianFactoryServer{ - staticPluginMedianConfig: staticPluginMedianConfig{ - provider: MedianProvider, - contractID: MedianContractID, - dataSource: DataSource, - juelsPerFeeCoinDataSource: JuelsPerFeeCoinDataSource, - gasPriceSubunitsDataSource: GasPriceSubunitsDataSource, - errorLog: errorlogtest.ErrorLog, - }, - } +func NewMedianFactoryServer(lggr logger.Logger) staticMedianFactoryServer { + return newStaticMedianFactoryServer(lggr, staticPluginMedianConfig{ + provider: MedianProvider(lggr), + contractID: MedianContractID, + dataSource: DataSource, + juelsPerFeeCoinDataSource: JuelsPerFeeCoinDataSource, + gasPriceSubunitsDataSource: GasPriceSubunitsDataSource, + errorLog: errorlogtest.ErrorLog, + }) +} - MedianProvider = staticMedianProvider{ - staticMedianProviderConfig: staticMedianProviderConfig{ - offchainDigester: ocr2test.OffchainConfigDigester, - contractTracker: ocr2test.ContractConfigTracker, - contractTransmitter: ocr2test.ContractTransmitter, - reportCodec: staticReportCodec{}, - medianContract: staticMedianContract{ - staticMedianContractConfig: staticMedianContractConfig{ - configDigest: libocr.ConfigDigest([32]byte{1: 1, 11: 8}), - epoch: 7, - round: 11, - latestAnswer: big.NewInt(123), - latestTimestamp: time.Unix(1234567890, 987654321).UTC(), - lookbackDuration: lookbackDuration, - }, +func MedianProvider(lggr logger.Logger) staticMedianProvider { + return newStaticMedianProvider(lggr, staticMedianProviderConfig{ + offchainDigester: ocr2test.OffchainConfigDigester, + contractTracker: ocr2test.ContractConfigTracker, + contractTransmitter: ocr2test.ContractTransmitter, + reportCodec: staticReportCodec{}, + medianContract: staticMedianContract{ + staticMedianContractConfig: staticMedianContractConfig{ + configDigest: libocr.ConfigDigest([32]byte{1: 1, 11: 8}), + epoch: 7, + round: 11, + latestAnswer: big.NewInt(123), + latestTimestamp: time.Unix(1234567890, 987654321).UTC(), + lookbackDuration: lookbackDuration, }, - onchainConfigCodec: staticOnchainConfigCodec{}, - contractReader: chaincomponentstest.ContractReader, }, - } + onchainConfigCodec: staticOnchainConfigCodec{}, + contractReader: chaincomponentstest.ContractReader, + }) +} - MedianContractID = "0x42" -) +var MedianContractID = "0x42" var ( encodedOnchainConfig = []byte{5: 11} diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test/mercury.go b/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test/mercury.go index da65e12a5..d07fa2e30 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test/mercury.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test/mercury.go @@ -11,10 +11,13 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" mercuryv1test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/v1/test" mercuryv2test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/v2/test" mercuryv3test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/v3/test" mercuryv4test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/v4/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" @@ -25,7 +28,7 @@ import ( ) func PluginMercury(t *testing.T, p types.PluginMercury) { - PluginMercuryTest{MercuryProvider}.TestPluginMercury(t, p) + PluginMercuryTest{MercuryProvider(logger.Test(t))}.TestPluginMercury(t, p) } type PluginMercuryTest struct { @@ -70,47 +73,51 @@ func (m PluginMercuryTest) TestPluginMercury(t *testing.T, p types.PluginMercury }) } -var FactoryServer = staticMercuryServer{ - provider: MercuryProvider, - dataSourceV1: mercuryv1test.DataSource, - dataSourceV2: mercuryv2test.DataSource, - dataSourceV3: mercuryv3test.DataSource, - dataSourceV4: mercuryv4test.DataSource, +func FactoryServer(lggr logger.Logger) staticMercuryServer { + return staticMercuryServer{ + staticMercuryProvider: MercuryProvider(lggr), + dataSourceV1: mercuryv1test.DataSource, + dataSourceV2: mercuryv2test.DataSource, + dataSourceV3: mercuryv3test.DataSource, + dataSourceV4: mercuryv4test.DataSource, + factory: newStaticMercuryPluginFactory(lggr), + } } var _ types.PluginMercury = staticMercuryServer{} type staticMercuryServer struct { - provider staticMercuryProvider + staticMercuryProvider dataSourceV1 mercuryv1test.DataSourceEvaluator dataSourceV2 mercuryv2test.DataSourceEvaluator dataSourceV3 mercuryv3test.DataSourceEvaluator dataSourceV4 mercuryv4test.DataSourceEvaluator + factory staticMercuryPluginFactory } var _ types.PluginMercury = staticMercuryServer{} func (s staticMercuryServer) commonValidation(ctx context.Context, provider types.MercuryProvider) error { ocd := provider.OffchainConfigDigester() - err := s.provider.offchainDigester.Evaluate(ctx, ocd) + err := s.offchainDigester.Evaluate(ctx, ocd) if err != nil { return fmt.Errorf("failed to evaluate offchainDigester: %w", err) } cct := provider.ContractConfigTracker() - err = s.provider.contractTracker.Evaluate(ctx, cct) + err = s.contractTracker.Evaluate(ctx, cct) if err != nil { return fmt.Errorf("failed to evaluate contractTracker: %w", err) } ct := provider.ContractTransmitter() - err = s.provider.contractTransmitter.Evaluate(ctx, ct) + err = s.contractTransmitter.Evaluate(ctx, ct) if err != nil { return fmt.Errorf("failed to evaluate contractTransmitter: %w", err) } occ := provider.OnchainConfigCodec() - err = s.provider.onchainConfigCodec.Evaluate(ctx, occ) + err = s.onchainConfigCodec.Evaluate(ctx, occ) if err != nil { return fmt.Errorf("failed to evaluate onchainConfigCodec: %w", err) } @@ -130,7 +137,7 @@ func (s staticMercuryServer) NewMercuryV4Factory(ctx context.Context, provider t } rc := provider.ReportCodecV4() - err = s.provider.reportCodecV4.Evaluate(ctx, rc) + err = s.reportCodecV4.Evaluate(ctx, rc) if err != nil { return nil, fmt.Errorf("failed to evaluate reportCodecV4: %w", err) } @@ -140,7 +147,7 @@ func (s staticMercuryServer) NewMercuryV4Factory(ctx context.Context, provider t return nil, fmt.Errorf("failed to evaluate dataSource: %w", err) } - return staticMercuryPluginFactory{}, nil + return s.factory, nil } func (s staticMercuryServer) NewMercuryV3Factory(ctx context.Context, provider types.MercuryProvider, dataSource mercuryv3types.DataSource) (types.MercuryPluginFactory, error) { @@ -156,7 +163,7 @@ func (s staticMercuryServer) NewMercuryV3Factory(ctx context.Context, provider t } rc := provider.ReportCodecV3() - err = s.provider.reportCodecV3.Evaluate(ctx, rc) + err = s.reportCodecV3.Evaluate(ctx, rc) if err != nil { return nil, fmt.Errorf("failed to evaluate reportCodecV3: %w", err) } @@ -166,7 +173,7 @@ func (s staticMercuryServer) NewMercuryV3Factory(ctx context.Context, provider t return nil, fmt.Errorf("failed to evaluate dataSource: %w", err) } - return staticMercuryPluginFactory{}, nil + return s.factory, nil } func (s staticMercuryServer) NewMercuryV2Factory(ctx context.Context, provider types.MercuryProvider, dataSource mercuryv2types.DataSource) (types.MercuryPluginFactory, error) { @@ -182,7 +189,7 @@ func (s staticMercuryServer) NewMercuryV2Factory(ctx context.Context, provider t } rc := provider.ReportCodecV2() - err = s.provider.reportCodecV2.Evaluate(ctx, rc) + err = s.reportCodecV2.Evaluate(ctx, rc) if err != nil { return nil, fmt.Errorf("failed to evaluate reportCodecV2: %w", err) } @@ -191,7 +198,7 @@ func (s staticMercuryServer) NewMercuryV2Factory(ctx context.Context, provider t if err != nil { return nil, fmt.Errorf("failed to evaluate dataSource: %w", err) } - return staticMercuryPluginFactory{}, nil + return s.factory, nil } func (s staticMercuryServer) NewMercuryV1Factory(ctx context.Context, provider types.MercuryProvider, dataSource mercuryv1types.DataSource) (types.MercuryPluginFactory, error) { @@ -207,7 +214,7 @@ func (s staticMercuryServer) NewMercuryV1Factory(ctx context.Context, provider t } rc := provider.ReportCodecV1() - err = s.provider.reportCodecV1.Evaluate(ctx, rc) + err = s.reportCodecV1.Evaluate(ctx, rc) if err != nil { return nil, fmt.Errorf("failed to evaluate reportCodecV1: %w", err) } @@ -217,20 +224,19 @@ func (s staticMercuryServer) NewMercuryV1Factory(ctx context.Context, provider t return nil, fmt.Errorf("failed to evaluate dataSource: %w", err) } - return staticMercuryPluginFactory{}, nil + return s.factory, nil } -type staticMercuryPluginFactory struct{} - -func (s staticMercuryPluginFactory) Name() string { panic("implement me") } - -func (s staticMercuryPluginFactory) Start(ctx context.Context) error { return nil } - -func (s staticMercuryPluginFactory) Close() error { return nil } - -func (s staticMercuryPluginFactory) Ready() error { panic("implement me") } +type staticMercuryPluginFactory struct { + services.Service +} -func (s staticMercuryPluginFactory) HealthReport() map[string]error { panic("implement me") } +func newStaticMercuryPluginFactory(lggr logger.Logger) staticMercuryPluginFactory { + lggr = logger.Named(lggr, "staticMercuryPluginFactory") + return staticMercuryPluginFactory{ + Service: test.NewStaticService(lggr), + } +} func (s staticMercuryPluginFactory) NewMercuryPlugin(ctx context.Context, config ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { if config.ConfigDigest != mercuryPluginConfig.ConfigDigest { diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test/provider.go b/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test/provider.go index e3d1e1b77..cc28d53c8 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test/provider.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test/provider.go @@ -7,10 +7,13 @@ import ( libocr "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" + "github.com/smartcontractkit/chainlink-common/pkg/logger" mercuryv1test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/v1/test" mercuryv2test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/v2/test" mercuryv3test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/v3/test" mercuryv4test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/v4/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" @@ -23,8 +26,8 @@ import ( testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" ) -var MercuryProvider = staticMercuryProvider{ - staticMercuryProviderConfig: staticMercuryProviderConfig{ +func MercuryProvider(lggr logger.Logger) staticMercuryProvider { + return newStaticMercuryProvider(lggr, staticMercuryProviderConfig{ offchainDigester: ocr2test.OffchainConfigDigester, contractTracker: ocr2test.ContractConfigTracker, contractTransmitter: ocr2test.ContractTransmitter, @@ -35,7 +38,7 @@ var MercuryProvider = staticMercuryProvider{ onchainConfigCodec: OnchainConfigCodec, mercuryChainReader: ChainReader, serviceFetcher: ServerFetcher, - }, + }) } type MercuryProviderTester interface { @@ -62,18 +65,17 @@ type staticMercuryProviderConfig struct { var _ types.MercuryProvider = staticMercuryProvider{} type staticMercuryProvider struct { + services.Service staticMercuryProviderConfig } -func (s staticMercuryProvider) Start(ctx context.Context) error { return nil } - -func (s staticMercuryProvider) Close() error { return nil } - -func (s staticMercuryProvider) Ready() error { panic("unimplemented") } - -func (s staticMercuryProvider) Name() string { panic("unimplemented") } - -func (s staticMercuryProvider) HealthReport() map[string]error { panic("unimplemented") } +func newStaticMercuryProvider(lggr logger.Logger, cfg staticMercuryProviderConfig) staticMercuryProvider { + lggr = logger.Named(lggr, "staticMercuryProvider") + return staticMercuryProvider{ + Service: test.NewStaticService(lggr), + staticMercuryProviderConfig: cfg, + } +} func (s staticMercuryProvider) OffchainConfigDigester() libocr.OffchainConfigDigester { return s.offchainDigester diff --git a/pkg/loop/internal/relayer/pluginprovider/ocr2/test/config.go b/pkg/loop/internal/relayer/pluginprovider/ocr2/test/config.go index 616dfc1b3..e7975d6e1 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ocr2/test/config.go +++ b/pkg/loop/internal/relayer/pluginprovider/ocr2/test/config.go @@ -8,7 +8,10 @@ import ( "github.com/stretchr/testify/assert" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" ) @@ -24,23 +27,21 @@ type staticConfigProviderConfig struct { contractConfigTracker testtypes.ContractConfigTrackerEvaluator } +var _ ConfigProviderTester = staticConfigProvider{} + // staticConfigProvider is a static implementation of ConfigProviderTester type staticConfigProvider struct { + services.Service staticConfigProviderConfig } -var _ ConfigProviderTester = staticConfigProvider{} - -// TODO validate start/Close calls? -func (s staticConfigProvider) Start(ctx context.Context) error { return nil } - -func (s staticConfigProvider) Close() error { return nil } - -func (s staticConfigProvider) Ready() error { panic("unimplemented") } - -func (s staticConfigProvider) Name() string { panic("unimplemented") } - -func (s staticConfigProvider) HealthReport() map[string]error { panic("unimplemented") } +func newStaticConfigProvider(lggr logger.Logger, cfg staticConfigProviderConfig) staticConfigProvider { + lggr = logger.Named(lggr, "staticConfigProvider") + return staticConfigProvider{ + Service: test.NewStaticService(lggr), + staticConfigProviderConfig: cfg, + } +} func (s staticConfigProvider) OffchainConfigDigester() libocr.OffchainConfigDigester { return s.offchainDigester diff --git a/pkg/loop/internal/relayer/pluginprovider/ocr2/test/plugin_provider.go b/pkg/loop/internal/relayer/pluginprovider/ocr2/test/plugin_provider.go index a73ef1e49..29c43fb29 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ocr2/test/plugin_provider.go +++ b/pkg/loop/internal/relayer/pluginprovider/ocr2/test/plugin_provider.go @@ -7,23 +7,31 @@ import ( libocr "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" + "github.com/smartcontractkit/chainlink-common/pkg/logger" chaincomponentstest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/contractreader/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" ) var _ types.PluginProvider = staticPluginProvider{} -var AgnosticProvider = staticPluginProvider{ - offchainConfigDigester: OffchainConfigDigester, - contractConfigTracker: ContractConfigTracker, - contractTransmitter: ContractTransmitter, - contractReader: chaincomponentstest.ContractReader, - codec: chaincomponentstest.Codec, +func AgnosticProvider(lggr logger.Logger) staticPluginProvider { + lggr = logger.Named(lggr, "staticPluginProvider") + return staticPluginProvider{ + Service: test.NewStaticService(lggr), + offchainConfigDigester: OffchainConfigDigester, + contractConfigTracker: ContractConfigTracker, + contractTransmitter: ContractTransmitter, + contractReader: chaincomponentstest.ContractReader, + codec: chaincomponentstest.Codec, + } } // staticPluginProvider is a static implementation of PluginProviderTester type staticPluginProvider struct { + services.Service offchainConfigDigester staticOffchainConfigDigester contractConfigTracker staticContractConfigTracker contractTransmitter testtypes.ContractTransmitterEvaluator @@ -33,16 +41,6 @@ type staticPluginProvider struct { var _ testtypes.PluginProviderTester = staticPluginProvider{} -func (s staticPluginProvider) Start(ctx context.Context) error { return nil } - -func (s staticPluginProvider) Close() error { return nil } - -func (s staticPluginProvider) Ready() error { panic("unimplemented") } - -func (s staticPluginProvider) Name() string { panic("unimplemented") } - -func (s staticPluginProvider) HealthReport() map[string]error { panic("unimplemented") } - func (s staticPluginProvider) OffchainConfigDigester() libocr.OffchainConfigDigester { return s.offchainConfigDigester } diff --git a/pkg/loop/internal/relayer/pluginprovider/ocr2/test/test.go b/pkg/loop/internal/relayer/pluginprovider/ocr2/test/test.go index 3af3c08f2..5f0112910 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ocr2/test/test.go +++ b/pkg/loop/internal/relayer/pluginprovider/ocr2/test/test.go @@ -4,7 +4,9 @@ import ( "github.com/smartcontractkit/libocr/commontypes" libocr "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" chaincomponentstest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/contractreader/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" ) const ( @@ -46,22 +48,6 @@ var ( }, } - // ConfigProvider is a static implementation of the ConfigProviderTester interface for testing - ConfigProvider = staticConfigProvider{ - staticConfigProviderConfig: staticConfigProviderConfig{ - offchainDigester: OffchainConfigDigester, - contractConfigTracker: ContractConfigTracker, - }, - } - - // AgnosticPluginProvider is a static implementation of the PluginProviderTester interface for testing - AgnosticPluginProvider = staticPluginProvider{ - offchainConfigDigester: OffchainConfigDigester, - contractConfigTracker: ContractConfigTracker, - contractTransmitter: ContractTransmitter, - contractReader: chaincomponentstest.ContractReader, - } - configDigest = libocr.ConfigDigest([32]byte{1: 7, 13: 11, 31: 23}) configDigestPrefix = libocr.ConfigDigestPrefix(99) @@ -84,3 +70,23 @@ var ( Round: round, } ) + +// ConfigProvider is a static implementation of the ConfigProviderTester interface for testing +func ConfigProvider(lggr logger.Logger) staticConfigProvider { + return newStaticConfigProvider(lggr, staticConfigProviderConfig{ + offchainDigester: OffchainConfigDigester, + contractConfigTracker: ContractConfigTracker, + }) +} + +// AgnosticPluginProvider is a static implementation of the PluginProviderTester interface for testing +func AgnosticPluginProvider(lggr logger.Logger) staticPluginProvider { + lggr = logger.Named(lggr, "staticPluginProvider") + return staticPluginProvider{ + Service: test.NewStaticService(lggr), + offchainConfigDigester: OffchainConfigDigester, + contractConfigTracker: ContractConfigTracker, + contractTransmitter: ContractTransmitter, + contractReader: chaincomponentstest.ContractReader, + } +} diff --git a/pkg/loop/internal/relayer/relayer.go b/pkg/loop/internal/relayer/relayer.go index e15470c3b..e50b8d06b 100644 --- a/pkg/loop/internal/relayer/relayer.go +++ b/pkg/loop/internal/relayer/relayer.go @@ -33,14 +33,15 @@ var _ looptypes.PluginRelayer = (*PluginRelayerClient)(nil) type PluginRelayerClient struct { *goplugin.PluginClient + *goplugin.ServiceClient - grpc pb.PluginRelayerClient + pluginRelayer pb.PluginRelayerClient } func NewPluginRelayerClient(broker net.Broker, brokerCfg net.BrokerConfig, conn *grpc.ClientConn) *PluginRelayerClient { brokerCfg.Logger = logger.Named(brokerCfg.Logger, "PluginRelayerClient") pc := goplugin.NewPluginClient(broker, brokerCfg, conn) - return &PluginRelayerClient{PluginClient: pc, grpc: pb.NewPluginRelayerClient(pc)} + return &PluginRelayerClient{PluginClient: pc, pluginRelayer: pb.NewPluginRelayerClient(pc), ServiceClient: goplugin.NewServiceClient(pc.BrokerExt, pc)} } func (p *PluginRelayerClient) NewRelayer(ctx context.Context, config string, keystore core.Keystore, capabilityRegistry core.CapabilitiesRegistry) (looptypes.Relayer, error) { @@ -62,7 +63,7 @@ func (p *PluginRelayerClient) NewRelayer(ctx context.Context, config string, key } deps.Add(capabilityRegistryResource) - reply, err := p.grpc.NewRelayer(ctx, &pb.NewRelayerRequest{ + reply, err := p.pluginRelayer.NewRelayer(ctx, &pb.NewRelayerRequest{ Config: config, KeystoreID: id, CapabilityRegistryID: capabilityRegistryID, @@ -84,6 +85,7 @@ type pluginRelayerServer struct { } func RegisterPluginRelayerServer(server *grpc.Server, broker net.Broker, brokerCfg net.BrokerConfig, impl looptypes.PluginRelayer) error { + pb.RegisterServiceServer(server, &goplugin.ServiceServer{Srv: impl}) pb.RegisterPluginRelayerServer(server, newPluginRelayerServer(broker, brokerCfg, impl)) return nil } @@ -191,7 +193,7 @@ type relayerClient struct { } func newRelayerClient(b *net.BrokerExt, conn grpc.ClientConnInterface) *relayerClient { - b = b.WithName("ChainRelayerClient") + b = b.WithName("RelayerClient") return &relayerClient{b, goplugin.NewServiceClient(b, conn), pb.NewRelayerClient(conn)} } diff --git a/pkg/loop/internal/relayer/test/relayer.go b/pkg/loop/internal/relayer/test/relayer.go index dd04ab902..d25cedbee 100644 --- a/pkg/loop/internal/relayer/test/relayer.go +++ b/pkg/loop/internal/relayer/test/relayer.go @@ -15,6 +15,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "github.com/smartcontractkit/chainlink-common/pkg/logger" keystoretest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/keystore/test" chaincomponentstest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/contractreader/test" cciptest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/ccip/test" @@ -22,8 +23,11 @@ import ( mercurytest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/mercury/test" ocr3capabilitytest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/ocr3capability/test" ocr2test "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ocr2/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" looptypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" @@ -51,7 +55,7 @@ type nodeResponse struct { nextPage string total int } -type staticPluginRelayerConfig struct { +type staticRelayerConfig struct { StaticChecks bool relayArgs types.RelayArgs pluginArgs types.PluginArgs @@ -72,46 +76,67 @@ type staticPluginRelayerConfig struct { chainStatus types.ChainStatus } -func NewRelayerTester(staticChecks bool) testtypes.RelayerTester { - return staticPluginRelayer{ - staticPluginRelayerConfig: staticPluginRelayerConfig{ - StaticChecks: staticChecks, - relayArgs: RelayArgs, - pluginArgs: PluginArgs, - contractReaderConfig: []byte("test"), - medianProvider: mediantest.MedianProvider, - mercuryProvider: mercurytest.MercuryProvider, - executionProvider: cciptest.ExecutionProvider, - agnosticProvider: ocr2test.AgnosticProvider, - configProvider: ocr2test.ConfigProvider, - ocr3CapabilityProvider: ocr3capabilitytest.OCR3CapabilityProvider, - contractReaderProvider: chaincomponentstest.ContractReader, - nodeRequest: nodeRequest{ - pageSize: 137, - pageToken: "", - }, - nodeResponse: nodeResponse{ - nodes: nodes, - nextPage: "", - total: len(nodes), - }, - transactionRequest: transactionRequest{ - from: "me", - to: "you", - amount: big.NewInt(97), - balanceCheck: true, - }, - chainStatus: chainStatus, +func newStaticRelayerConfig(lggr logger.Logger, staticChecks bool) staticRelayerConfig { + return staticRelayerConfig{ + StaticChecks: staticChecks, + relayArgs: RelayArgs, + pluginArgs: PluginArgs, + contractReaderConfig: []byte("test"), + medianProvider: mediantest.MedianProvider(lggr), + mercuryProvider: mercurytest.MercuryProvider(lggr), + executionProvider: cciptest.ExecutionProvider(lggr), + agnosticProvider: ocr2test.AgnosticProvider(lggr), + configProvider: ocr2test.ConfigProvider(lggr), + ocr3CapabilityProvider: ocr3capabilitytest.OCR3CapabilityProvider, + contractReaderProvider: chaincomponentstest.ContractReader, + nodeRequest: nodeRequest{ + pageSize: 137, + pageToken: "", + }, + nodeResponse: nodeResponse{ + nodes: nodes, + nextPage: "", + total: len(nodes), + }, + transactionRequest: transactionRequest{ + from: "me", + to: "you", + amount: big.NewInt(97), + balanceCheck: true, }, + chainStatus: chainStatus, } } +func NewPluginRelayer(lggr logger.Logger, staticChecks bool) looptypes.PluginRelayer { + return newStaticPluginRelayer(lggr, staticChecks) +} + +func NewRelayerTester(lggr logger.Logger, staticChecks bool) testtypes.RelayerTester { + return newStaticRelayer(lggr, staticChecks) +} + type staticPluginRelayer struct { - staticPluginRelayerConfig + services.Service + relayer staticRelayer +} + +func newStaticPluginRelayer(lggr logger.Logger, staticChecks bool) staticPluginRelayer { + lggr = logger.Named(lggr, "staticPluginRelayer") + return staticPluginRelayer{ + Service: test.NewStaticService(lggr), + relayer: newStaticRelayer(lggr, staticChecks), + } +} + +func (s staticPluginRelayer) HealthReport() map[string]error { + hp := s.Service.HealthReport() + services.CopyHealth(hp, s.relayer.HealthReport()) + return hp } func (s staticPluginRelayer) NewRelayer(ctx context.Context, config string, keystore core.Keystore, capabilityRegistry core.CapabilitiesRegistry) (looptypes.Relayer, error) { - if s.StaticChecks && config != ConfigTOML { + if s.relayer.StaticChecks && config != ConfigTOML { return nil, fmt.Errorf("expected config %q but got %q", ConfigTOML, config) } keys, err := keystore.Accounts(ctx) @@ -122,38 +147,55 @@ func (s staticPluginRelayer) NewRelayer(ctx context.Context, config string, keys return nil, fmt.Errorf("expected at least one key but got none") } - return s, nil + return s.relayer, nil } -func (s staticPluginRelayer) Start(ctx context.Context) error { return nil } - -func (s staticPluginRelayer) Close() error { return nil } - -func (s staticPluginRelayer) Ready() error { panic("unimplemented") } +type staticRelayer struct { + services.Service + staticRelayerConfig +} -func (s staticPluginRelayer) Name() string { panic("unimplemented") } +func newStaticRelayer(lggr logger.Logger, staticChecks bool) staticRelayer { + lggr = logger.Named(lggr, "staticRelayer") + cfg := newStaticRelayerConfig(lggr, staticChecks) + return staticRelayer{ + Service: test.NewStaticService(lggr), + staticRelayerConfig: cfg, + } +} -func (s staticPluginRelayer) HealthReport() map[string]error { panic("unimplemented") } +func (s staticRelayer) HealthReport() map[string]error { + hp := s.Service.HealthReport() + services.CopyHealth(hp, s.contractReaderProvider.HealthReport()) + services.CopyHealth(hp, s.configProvider.HealthReport()) + services.CopyHealth(hp, s.medianProvider.HealthReport()) + services.CopyHealth(hp, s.agnosticProvider.HealthReport()) + services.CopyHealth(hp, s.ocr3CapabilityProvider.HealthReport()) + services.CopyHealth(hp, s.mercuryProvider.HealthReport()) + services.CopyHealth(hp, s.executionProvider.HealthReport()) + services.CopyHealth(hp, s.commitProvider.HealthReport()) + return hp +} -func (s staticPluginRelayer) NewContractWriter(_ context.Context, _ []byte) (types.ContractWriter, error) { +func (s staticRelayer) NewContractWriter(_ context.Context, _ []byte) (types.ContractWriter, error) { return nil, errors.New("not implemented") } -func (s staticPluginRelayer) NewContractReader(_ context.Context, contractReaderConfig []byte) (types.ContractReader, error) { +func (s staticRelayer) NewContractReader(_ context.Context, contractReaderConfig []byte) (types.ContractReader, error) { if s.StaticChecks && !(bytes.Equal(s.contractReaderConfig, contractReaderConfig)) { return nil, fmt.Errorf("expected contractReaderConfig:\n\t%v\nbut got:\n\t%v", string(s.contractReaderConfig), string(contractReaderConfig)) } return s.contractReaderProvider, nil } -func (s staticPluginRelayer) NewConfigProvider(ctx context.Context, r types.RelayArgs) (types.ConfigProvider, error) { +func (s staticRelayer) NewConfigProvider(ctx context.Context, r types.RelayArgs) (types.ConfigProvider, error) { if s.StaticChecks && !equalRelayArgs(r, s.relayArgs) { return nil, fmt.Errorf("expected relay args:\n\t%v\nbut got:\n\t%v", s.relayArgs, r) } return s.configProvider, nil } -func (s staticPluginRelayer) NewMedianProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.MedianProvider, error) { +func (s staticRelayer) NewMedianProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.MedianProvider, error) { if s.StaticChecks { ra := newRelayArgsWithProviderType(types.Median) if !equalRelayArgs(r, ra) { @@ -167,7 +209,7 @@ func (s staticPluginRelayer) NewMedianProvider(ctx context.Context, r types.Rela return s.medianProvider, nil } -func (s staticPluginRelayer) NewPluginProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.PluginProvider, error) { +func (s staticRelayer) NewPluginProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.PluginProvider, error) { if s.StaticChecks { ra := newRelayArgsWithProviderType(types.Median) if !equalRelayArgs(r, ra) { @@ -180,7 +222,7 @@ func (s staticPluginRelayer) NewPluginProvider(ctx context.Context, r types.Rela return s.agnosticProvider, nil } -func (s staticPluginRelayer) NewOCR3CapabilityProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.OCR3CapabilityProvider, error) { +func (s staticRelayer) NewOCR3CapabilityProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.OCR3CapabilityProvider, error) { if s.StaticChecks { ra := newRelayArgsWithProviderType(types.OCR3Capability) if !equalRelayArgs(r, ra) { @@ -193,7 +235,7 @@ func (s staticPluginRelayer) NewOCR3CapabilityProvider(ctx context.Context, r ty return s.ocr3CapabilityProvider, nil } -func (s staticPluginRelayer) NewMercuryProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.MercuryProvider, error) { +func (s staticRelayer) NewMercuryProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.MercuryProvider, error) { if s.StaticChecks { if !equalRelayArgs(r, mercurytest.RelayArgs) { return nil, fmt.Errorf("expected relay args:\n\t%v\nbut got:\n\t%v", mercurytest.RelayArgs, r) @@ -205,7 +247,7 @@ func (s staticPluginRelayer) NewMercuryProvider(ctx context.Context, r types.Rel return s.mercuryProvider, nil } -func (s staticPluginRelayer) NewExecutionProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.CCIPExecProvider, error) { +func (s staticRelayer) NewExecutionProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.CCIPExecProvider, error) { if s.StaticChecks { if !equalRelayArgs(r, cciptest.ExecutionRelayArgs) { return nil, fmt.Errorf("expected relay args:\n\t%v\nbut got:\n\t%v", cciptest.ExecutionRelayArgs, r) @@ -217,7 +259,7 @@ func (s staticPluginRelayer) NewExecutionProvider(ctx context.Context, r types.R return s.executionProvider, nil } -func (s staticPluginRelayer) NewCommitProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.CCIPCommitProvider, error) { +func (s staticRelayer) NewCommitProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.CCIPCommitProvider, error) { if s.StaticChecks { if !equalRelayArgs(r, cciptest.CommitRelayArgs) { return nil, fmt.Errorf("expected relay args:\n\t%v\nbut got:\n\t%v", cciptest.CommitRelayArgs, r) @@ -229,19 +271,19 @@ func (s staticPluginRelayer) NewCommitProvider(ctx context.Context, r types.Rela return s.commitProvider, nil } -func (s staticPluginRelayer) NewLLOProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.LLOProvider, error) { +func (s staticRelayer) NewLLOProvider(ctx context.Context, r types.RelayArgs, p types.PluginArgs) (types.LLOProvider, error) { return nil, errors.New("not implemented") } -func (s staticPluginRelayer) LatestHead(ctx context.Context) (types.Head, error) { +func (s staticRelayer) LatestHead(ctx context.Context) (types.Head, error) { return types.Head{}, errors.New("not implemented") } -func (s staticPluginRelayer) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { +func (s staticRelayer) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { return s.chainStatus, nil } -func (s staticPluginRelayer) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) ([]types.NodeStatus, string, int, error) { +func (s staticRelayer) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) ([]types.NodeStatus, string, int, error) { if s.StaticChecks && s.nodeRequest.pageSize != pageSize { return nil, "", -1, fmt.Errorf("expected page_size %d but got %d", s.nodeRequest.pageSize, pageSize) } @@ -251,7 +293,7 @@ func (s staticPluginRelayer) ListNodeStatuses(ctx context.Context, pageSize int3 return s.nodeResponse.nodes, s.nodeResponse.nextPage, s.nodeResponse.total, nil } -func (s staticPluginRelayer) Transact(ctx context.Context, f, t string, a *big.Int, b bool) error { +func (s staticRelayer) Transact(ctx context.Context, f, t string, a *big.Int, b bool) error { if s.StaticChecks { if f != s.transactionRequest.from { return fmt.Errorf("expected from %s but got %s", s.transactionRequest.from, f) @@ -270,15 +312,13 @@ func (s staticPluginRelayer) Transact(ctx context.Context, f, t string, a *big.I return nil } -func (s staticPluginRelayer) AssertEqual(_ context.Context, t *testing.T, relayer looptypes.Relayer) { +func (s staticRelayer) AssertEqual(_ context.Context, t *testing.T, relayer looptypes.Relayer) { t.Run("ContractReader", func(t *testing.T) { t.Parallel() ctx := tests.Context(t) contractReader, err := relayer.NewContractReader(ctx, []byte("test")) require.NoError(t, err) - require.NoError(t, contractReader.Start(ctx)) - - t.Cleanup(func() { assert.NoError(t, contractReader.Close()) }) + servicetest.Run(t, contractReader) }) t.Run("ConfigProvider", func(t *testing.T) { @@ -286,8 +326,7 @@ func (s staticPluginRelayer) AssertEqual(_ context.Context, t *testing.T, relaye ctx := tests.Context(t) configProvider, err := relayer.NewConfigProvider(ctx, RelayArgs) require.NoError(t, err) - require.NoError(t, configProvider.Start(ctx)) - t.Cleanup(func() { assert.NoError(t, configProvider.Close()) }) + servicetest.Run(t, configProvider) s.configProvider.AssertEqual(ctx, t, configProvider) }) @@ -300,8 +339,7 @@ func (s staticPluginRelayer) AssertEqual(_ context.Context, t *testing.T, relaye require.NoError(t, err) require.NotNil(t, p) provider := p.(types.MedianProvider) - require.NoError(t, provider.Start(ctx)) - t.Cleanup(func() { assert.NoError(t, provider.Close()) }) + servicetest.Run(t, provider) t.Run("ReportingPluginProvider", func(t *testing.T) { t.Parallel() @@ -315,8 +353,7 @@ func (s staticPluginRelayer) AssertEqual(_ context.Context, t *testing.T, relaye ra := newRelayArgsWithProviderType(types.GenericPlugin) provider, err := relayer.NewPluginProvider(ctx, ra, PluginArgs) require.NoError(t, err) - require.NoError(t, provider.Start(ctx)) - t.Cleanup(func() { assert.NoError(t, provider.Close()) }) + servicetest.Run(t, provider) t.Run("ReportingPluginProvider", func(t *testing.T) { t.Parallel() ctx := tests.Context(t) @@ -374,15 +411,23 @@ func RunPlugin(t *testing.T, p looptypes.PluginRelayer) { ctx := tests.Context(t) relayer, err := p.NewRelayer(ctx, ConfigTOML, keystoretest.Keystore, nil) require.NoError(t, err) - require.NoError(t, relayer.Start(ctx)) - t.Cleanup(func() { assert.NoError(t, relayer.Close()) }) + servicetest.Run(t, relayer) Run(t, relayer) + servicetest.AssertHealthReportNames(t, relayer.HealthReport(), + "PluginRelayerClient", //TODO missing + "PluginRelayerClient.RelayerClient", + "PluginRelayerClient.RelayerClient.staticPluginRelayer", //TODO missing + "PluginRelayerClient.RelayerClient.staticPluginRelayer.staticRelayer", + "PluginRelayerClient.RelayerClient.staticPluginRelayer.staticRelayer.staticMedianProvider", + "PluginRelayerClient.RelayerClient.staticPluginRelayer.staticRelayer.staticPluginProvider", + "PluginRelayerClient.RelayerClient.staticPluginRelayer.staticRelayer.staticConfigProvider", + ) }) } func Run(t *testing.T, relayer looptypes.Relayer) { ctx := tests.Context(t) - expectedRelayer := NewRelayerTester(false) + expectedRelayer := NewRelayerTester(logger.Test(t), false) expectedRelayer.AssertEqual(ctx, t, relayer) } diff --git a/pkg/loop/internal/reportingplugin/median/median.go b/pkg/loop/internal/reportingplugin/median/median.go index a6b53fc68..a768c4359 100644 --- a/pkg/loop/internal/reportingplugin/median/median.go +++ b/pkg/loop/internal/reportingplugin/median/median.go @@ -110,6 +110,7 @@ type pluginMedianServer struct { } func RegisterPluginMedianServer(server *grpc.Server, broker net.Broker, brokerCfg net.BrokerConfig, impl core.PluginMedian) error { + pb.RegisterServiceServer(server, &goplugin.ServiceServer{Srv: impl}) pb.RegisterPluginMedianServer(server, newPluginMedianServer(&net.BrokerExt{Broker: broker, BrokerConfig: brokerCfg}, impl)) return nil } @@ -164,6 +165,10 @@ func (m *pluginMedianServer) NewMedianFactory(ctx context.Context, request *pb.N m.CloseAll(dsRes, juelsRes, gasPriceSubunitsRes, providerRes, errorLogRes) return nil, err } + if err = factory.Start(ctx); err != nil { + m.CloseAll(dsRes, juelsRes, gasPriceSubunitsRes, providerRes, errorLogRes) + return nil, err + } id, _, err := m.ServeNew("ReportingPluginProvider", func(s *grpc.Server) { pb.RegisterServiceServer(s, &goplugin.ServiceServer{Srv: factory}) diff --git a/pkg/loop/internal/reportingplugin/test/factory.go b/pkg/loop/internal/reportingplugin/test/factory.go index d07e88544..d9f87ef34 100644 --- a/pkg/loop/internal/reportingplugin/test/factory.go +++ b/pkg/loop/internal/reportingplugin/test/factory.go @@ -8,8 +8,11 @@ import ( libocr "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" validationtest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/validation/test" + "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test" testtypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/test/types" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" @@ -18,12 +21,14 @@ import ( "github.com/stretchr/testify/require" ) -var Factory = staticFactory{ - staticFactoryConfig: staticFactoryConfig{ - ReportingPluginConfig: reportingPluginConfig, - rpi: rpi, - reportingPlugin: ReportingPlugin, - }, +func Factory(lggr logger.Logger) staticFactory { + return newStaticFactory(lggr, StaticFactoryConfig) +} + +var StaticFactoryConfig = staticFactoryConfig{ + ReportingPluginConfig: reportingPluginConfig, + rpi: rpi, + reportingPlugin: ReportingPlugin, } type staticFactoryConfig struct { @@ -33,20 +38,19 @@ type staticFactoryConfig struct { } type staticFactory struct { + services.Service staticFactoryConfig } -var _ types.ReportingPluginFactory = staticFactory{} - -func (s staticFactory) Name() string { panic("implement me") } - -func (s staticFactory) Start(ctx context.Context) error { return nil } - -func (s staticFactory) Close() error { return nil } - -func (s staticFactory) Ready() error { panic("implement me") } +func newStaticFactory(lggr logger.Logger, cfg staticFactoryConfig) staticFactory { + lggr = logger.Named(lggr, "staticFactory") + return staticFactory{ + Service: test.NewStaticService(lggr), + staticFactoryConfig: cfg, + } +} -func (s staticFactory) HealthReport() map[string]error { panic("implement me") } +var _ types.ReportingPluginFactory = staticFactory{} func (s staticFactory) NewReportingPlugin(ctx context.Context, config libocr.ReportingPluginConfig) (libocr.ReportingPlugin, libocr.ReportingPluginInfo, error) { err := s.equalConfig(config) @@ -97,7 +101,7 @@ func (s staticFactory) equalConfig(other libocr.ReportingPluginConfig) error { } func RunFactory(t *testing.T, factory libocr.ReportingPluginFactory) { - expectedFactory := Factory + expectedFactory := Factory(logger.Test(t)) t.Run("ReportingPluginFactory", func(t *testing.T) { ctx := tests.Context(t) rp, gotRPI, err := factory.NewReportingPlugin(ctx, expectedFactory.ReportingPluginConfig) diff --git a/pkg/loop/internal/test/cmd/main.go b/pkg/loop/internal/test/cmd/main.go index 2c5bcf833..1f9c7d8cd 100644 --- a/pkg/loop/internal/test/cmd/main.go +++ b/pkg/loop/internal/test/cmd/main.go @@ -73,7 +73,7 @@ func main() { HandshakeConfig: loop.PluginRelayerHandshakeConfig(), Plugins: map[string]plugin.Plugin{ loop.PluginRelayerName: &loop.GRPCPluginRelayer{ - PluginServer: relayertest.NewRelayerTester(staticChecks), + PluginServer: relayertest.NewPluginRelayer(lggr, staticChecks), BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}, }, }, @@ -100,7 +100,7 @@ func main() { HandshakeConfig: loop.PluginMedianHandshakeConfig(), Plugins: map[string]plugin.Plugin{ loop.PluginMedianName: &loop.GRPCPluginMedian{ - PluginServer: mediantest.MedianFactoryServer, + PluginServer: mediantest.NewMedianFactoryServer(lggr), BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}}, }, GRPCServer: grpcServer, @@ -122,8 +122,7 @@ func main() { HandshakeConfig: reportingplugins.ReportingPluginHandshakeConfig(), Plugins: map[string]plugin.Plugin{ reportingplugins.PluginServiceName: &reportingplugins.GRPCService[types.PluginProvider]{ - //PluginServer: test.StaticReportingPluginWithPluginProvider{}, - PluginServer: ocr2test.AgnosticProviderServer, + PluginServer: ocr2test.AgnosticProviderServer(lggr), BrokerConfig: loop.BrokerConfig{ Logger: lggr, @@ -140,8 +139,7 @@ func main() { HandshakeConfig: reportingplugins.ReportingPluginHandshakeConfig(), Plugins: map[string]plugin.Plugin{ reportingplugins.PluginServiceName: &reportingplugins.GRPCService[types.MedianProvider]{ - //PluginServer: test.StaticReportingPluginWithMedianProvider{}, - PluginServer: ocr2test.MedianProviderServer, + PluginServer: ocr2test.MedianProviderServer(lggr), BrokerConfig: loop.BrokerConfig{ Logger: lggr, StopCh: stopCh, @@ -158,7 +156,7 @@ func main() { HandshakeConfig: loop.PluginMercuryHandshakeConfig(), Plugins: map[string]plugin.Plugin{ loop.PluginMercuryName: &loop.GRPCPluginMercury{ - PluginServer: mercurytest.FactoryServer, + PluginServer: mercurytest.FactoryServer(lggr), BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}}, }, GRPCServer: grpcServer, @@ -172,7 +170,7 @@ func main() { HandshakeConfig: loop.PluginCCIPExecutionHandshakeConfig(), Plugins: map[string]plugin.Plugin{ loop.CCIPExecutionLOOPName: &loop.ExecutionLoop{ - PluginServer: cciptest.ExecFactoryServer, + PluginServer: cciptest.ExecFactoryServer(lggr), BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}}, }, GRPCServer: grpcServer, @@ -186,7 +184,7 @@ func main() { HandshakeConfig: loop.PluginCCIPCommitHandshakeConfig(), Plugins: map[string]plugin.Plugin{ loop.CCIPCommitLOOPName: &loop.CommitLoop{ - PluginServer: cciptest.CommitFactoryServer, + PluginServer: cciptest.CommitFactoryServer(lggr), BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}}, }, GRPCServer: grpcServer, @@ -199,7 +197,7 @@ func main() { HandshakeConfig: reportingplugins.ReportingPluginHandshakeConfig(), Plugins: map[string]plugin.Plugin{ ocr3.PluginServiceName: &ocr3.GRPCService[types.PluginProvider]{ - PluginServer: ocr3test.AgnosticPluginServer, + PluginServer: ocr3test.AgnosticPluginServer(lggr), BrokerConfig: loop.BrokerConfig{ Logger: lggr, StopCh: stopCh, @@ -215,7 +213,7 @@ func main() { HandshakeConfig: reportingplugins.ReportingPluginHandshakeConfig(), Plugins: map[string]plugin.Plugin{ ocr3.PluginServiceName: &ocr3.GRPCService[types.MedianProvider]{ - PluginServer: ocr3test.MedianServer, + PluginServer: ocr3test.MedianServer(lggr), BrokerConfig: loop.BrokerConfig{ Logger: lggr, StopCh: stopCh, diff --git a/pkg/loop/internal/test/test.go b/pkg/loop/internal/test/test.go index ef1edcb09..d7bf107ac 100644 --- a/pkg/loop/internal/test/test.go +++ b/pkg/loop/internal/test/test.go @@ -4,6 +4,9 @@ import ( "context" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/services" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" ) const ConfigTOML = `[Foo] @@ -33,3 +36,32 @@ type baseCapability struct { func (e baseCapability) Info(ctx context.Context) (capabilities.CapabilityInfo, error) { return CapabilityInfo, nil } + +type staticService struct { + lggr logger.Logger +} + +func NewStaticService(lggr logger.Logger) services.Service { + return staticService{lggr: lggr} +} +func (s staticService) Name() string { return s.lggr.Name() } + +func (s staticService) Start(ctx context.Context) error { + s.lggr.Info("Started") + return nil +} + +func (s staticService) Close() error { + s.lggr.Info("Closed") + return nil +} + +func (s staticService) Ready() error { + s.lggr.Info("Ready") + return nil +} + +// HealthReport reports only for this single service. Override to include sub-services. +func (s staticService) HealthReport() map[string]error { + return map[string]error{s.Name(): s.Ready()} +} diff --git a/pkg/loop/internal/test/types/interfaces.go b/pkg/loop/internal/test/types/interfaces.go index 8da33d419..d044671ae 100644 --- a/pkg/loop/internal/test/types/interfaces.go +++ b/pkg/loop/internal/test/types/interfaces.go @@ -95,7 +95,6 @@ type MedianProviderTester interface { } type RelayerTester interface { - looptypes.PluginRelayer looptypes.Relayer // implements all the possible providers as a one-stop shop for testing looptypes.MercuryProvider diff --git a/pkg/loop/internal/types/types.go b/pkg/loop/internal/types/types.go index 30f8a73fa..2fa339d54 100644 --- a/pkg/loop/internal/types/types.go +++ b/pkg/loop/internal/types/types.go @@ -10,6 +10,7 @@ import ( ) type PluginRelayer interface { + services.Service NewRelayer(ctx context.Context, config string, keystore core.Keystore, capabilityRegistry core.CapabilitiesRegistry) (Relayer, error) } diff --git a/pkg/loop/keystore_service.go b/pkg/loop/keystore_service.go index 1cd93dad7..5519c0f79 100644 --- a/pkg/loop/keystore_service.go +++ b/pkg/loop/keystore_service.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/goplugin" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/keystore" + "github.com/smartcontractkit/chainlink-common/pkg/services" ) // KeystoreService is a [types.Service] that maintains an internal [keystore.Keystore]. @@ -16,12 +17,12 @@ type KeystoreService struct { } func NewKeystoreService(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, config []byte) *KeystoreService { - newService := func(ctx context.Context, instance any) (keystore.GRPCService, error) { + newService := func(ctx context.Context, instance any) (keystore.GRPCService, services.HealthReporter, error) { plug, ok := instance.(*keystore.Client) if !ok { - return nil, fmt.Errorf("expected PluginKeystore but got %T", instance) + return nil, nil, fmt.Errorf("expected PluginKeystore but got %T", instance) } - return plug, nil + return plug, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "KeystoreService") diff --git a/pkg/loop/median_service.go b/pkg/loop/median_service.go index eec104f7f..ad9a40f06 100644 --- a/pkg/loop/median_service.go +++ b/pkg/loop/median_service.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/goplugin" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) @@ -24,12 +25,17 @@ type MedianService struct { // NewMedianService returns a new [*MedianService]. // cmd must return a new exec.Cmd each time it is called. func NewMedianService(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, provider types.MedianProvider, contractAddress string, dataSource, juelsPerFeeCoin, gasPriceSubunits median.DataSource, errorLog core.ErrorLog) *MedianService { - newService := func(ctx context.Context, instance any) (types.ReportingPluginFactory, error) { + newService := func(ctx context.Context, instance any) (types.ReportingPluginFactory, services.HealthReporter, error) { plug, ok := instance.(core.PluginMedian) if !ok { - return nil, fmt.Errorf("expected PluginMedian but got %T", instance) + return nil, nil, fmt.Errorf("expected PluginMedian but got %T", instance) } - return plug.NewMedianFactory(ctx, provider, contractAddress, dataSource, juelsPerFeeCoin, gasPriceSubunits, errorLog) + //TODO plug.Start(ctx)? (how to close?) + factory, err := plug.NewMedianFactory(ctx, provider, contractAddress, dataSource, juelsPerFeeCoin, gasPriceSubunits, errorLog) + if err != nil { + return nil, nil, err + } + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "MedianService") diff --git a/pkg/loop/median_service_test.go b/pkg/loop/median_service_test.go index d0f84e877..eed99bf38 100644 --- a/pkg/loop/median_service_test.go +++ b/pkg/loop/median_service_test.go @@ -18,9 +18,10 @@ import ( func TestMedianService(t *testing.T) { t.Parallel() - median := loop.NewMedianService(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + lggr := logger.Test(t) + median := loop.NewMedianService(lggr, loop.GRPCOpts{}, func() *exec.Cmd { return NewHelperProcessCommand(loop.PluginMedianName, false, 0) - }, mediantest.MedianProvider, mediantest.MedianContractID, mediantest.DataSource, mediantest.JuelsPerFeeCoinDataSource, mediantest.GasPriceSubunitsDataSource, errorlogtest.ErrorLog) + }, mediantest.MedianProvider(lggr), mediantest.MedianContractID, mediantest.DataSource, mediantest.JuelsPerFeeCoinDataSource, mediantest.GasPriceSubunitsDataSource, errorlogtest.ErrorLog) hook := median.PluginService.XXXTestHook() servicetest.Run(t, median) @@ -49,14 +50,14 @@ func TestMedianService(t *testing.T) { func TestMedianService_recovery(t *testing.T) { t.Parallel() + lggr := logger.Test(t) var limit atomic.Int32 - median := loop.NewMedianService(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { - h := HelperProcessCommand{ + median := loop.NewMedianService(lggr, loop.GRPCOpts{}, func() *exec.Cmd { + return HelperProcessCommand{ Command: loop.PluginMedianName, Limit: int(limit.Add(1)), - } - return h.New() - }, mediantest.MedianProvider, mediantest.MedianContractID, mediantest.DataSource, mediantest.JuelsPerFeeCoinDataSource, mediantest.GasPriceSubunitsDataSource, errorlogtest.ErrorLog) + }.New() + }, mediantest.MedianProvider(lggr), mediantest.MedianContractID, mediantest.DataSource, mediantest.JuelsPerFeeCoinDataSource, mediantest.GasPriceSubunitsDataSource, errorlogtest.ErrorLog) servicetest.Run(t, median) reportingplugintest.RunFactory(t, median) diff --git a/pkg/loop/mercury_service.go b/pkg/loop/mercury_service.go index 1696c343c..c43fa2b88 100644 --- a/pkg/loop/mercury_service.go +++ b/pkg/loop/mercury_service.go @@ -9,6 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/goplugin" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" mercury_v1_types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" mercury_v2_types "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" @@ -28,12 +29,17 @@ var _ ocr3types.MercuryPluginFactory = (*MercuryV4Service)(nil) // NewMercuryV4Service returns a new [*MercuryV4Service]. // cmd must return a new exec.Cmd each time it is called. func NewMercuryV4Service(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, provider types.MercuryProvider, dataSource mercury_v4_types.DataSource) *MercuryV4Service { - newService := func(ctx context.Context, instance any) (types.MercuryPluginFactory, error) { + newService := func(ctx context.Context, instance any) (types.MercuryPluginFactory, services.HealthReporter, error) { plug, ok := instance.(types.PluginMercury) if !ok { - return nil, fmt.Errorf("expected PluginMercury but got %T", instance) + return nil, nil, fmt.Errorf("expected PluginMercury but got %T", instance) } - return plug.NewMercuryV4Factory(ctx, provider, dataSource) + factory, err := plug.NewMercuryV4Factory(ctx, provider, dataSource) + if err != nil { + return nil, nil, err + + } + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "MercuryV3") @@ -62,12 +68,16 @@ var _ ocr3types.MercuryPluginFactory = (*MercuryV3Service)(nil) // NewMercuryV3Service returns a new [*MercuryV3Service]. // cmd must return a new exec.Cmd each time it is called. func NewMercuryV3Service(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, provider types.MercuryProvider, dataSource mercury_v3_types.DataSource) *MercuryV3Service { - newService := func(ctx context.Context, instance any) (types.MercuryPluginFactory, error) { + newService := func(ctx context.Context, instance any) (types.MercuryPluginFactory, services.HealthReporter, error) { plug, ok := instance.(types.PluginMercury) if !ok { - return nil, fmt.Errorf("expected PluginMercury but got %T", instance) + return nil, nil, fmt.Errorf("expected PluginMercury but got %T", instance) + } + factory, err := plug.NewMercuryV3Factory(ctx, provider, dataSource) + if err != nil { + return nil, nil, err } - return plug.NewMercuryV3Factory(ctx, provider, dataSource) + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "MercuryV3") @@ -94,12 +104,16 @@ var _ ocr3types.MercuryPluginFactory = (*MercuryV1Service)(nil) // NewMercuryV1Service returns a new [*MercuryV1Service]. // cmd must return a new exec.Cmd each time it is called. func NewMercuryV1Service(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, provider types.MercuryProvider, dataSource mercury_v1_types.DataSource) *MercuryV1Service { - newService := func(ctx context.Context, instance any) (types.MercuryPluginFactory, error) { + newService := func(ctx context.Context, instance any) (types.MercuryPluginFactory, services.HealthReporter, error) { plug, ok := instance.(types.PluginMercury) if !ok { - return nil, fmt.Errorf("expected PluginMercury but got %T", instance) + return nil, nil, fmt.Errorf("expected PluginMercury but got %T", instance) } - return plug.NewMercuryV1Factory(ctx, provider, dataSource) + factory, err := plug.NewMercuryV1Factory(ctx, provider, dataSource) + if err != nil { + return nil, nil, err + } + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "MercuryV1") @@ -128,12 +142,16 @@ var _ ocr3types.MercuryPluginFactory = (*MercuryV2Service)(nil) // NewMercuryV2Service returns a new [*MercuryV2Service]. // cmd must return a new exec.Cmd each time it is called. func NewMercuryV2Service(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, provider types.MercuryProvider, dataSource mercury_v2_types.DataSource) *MercuryV2Service { - newService := func(ctx context.Context, instance any) (types.MercuryPluginFactory, error) { + newService := func(ctx context.Context, instance any) (types.MercuryPluginFactory, services.HealthReporter, error) { plug, ok := instance.(types.PluginMercury) if !ok { - return nil, fmt.Errorf("expected PluginMercury but got %T", instance) + return nil, nil, fmt.Errorf("expected PluginMercury but got %T", instance) + } + factory, err := plug.NewMercuryV2Factory(ctx, provider, dataSource) + if err != nil { + return nil, nil, err } - return plug.NewMercuryV2Factory(ctx, provider, dataSource) + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "MercuryV2") diff --git a/pkg/loop/mercury_service_test.go b/pkg/loop/mercury_service_test.go index e0bcfe1c8..aa6d231ed 100644 --- a/pkg/loop/mercury_service_test.go +++ b/pkg/loop/mercury_service_test.go @@ -20,9 +20,10 @@ import ( func TestMercuryV4Service(t *testing.T) { t.Parallel() - mercuryV4 := loop.NewMercuryV4Service(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + lggr := logger.Test(t) + mercuryV4 := loop.NewMercuryV4Service(lggr, loop.GRPCOpts{}, func() *exec.Cmd { return NewHelperProcessCommand(loop.PluginMercuryName, true, 0) - }, mercurytest.MercuryProvider, mercuryv4test.DataSource) + }, mercurytest.MercuryProvider(lggr), mercuryv4test.DataSource) hook := mercuryV4.PluginService.XXXTestHook() servicetest.Run(t, mercuryV4) @@ -51,14 +52,15 @@ func TestMercuryV4Service(t *testing.T) { func TestMercuryV4Service_recovery(t *testing.T) { t.Parallel() + lggr := logger.Test(t) var limit atomic.Int32 - mercury := loop.NewMercuryV4Service(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + mercury := loop.NewMercuryV4Service(lggr, loop.GRPCOpts{}, func() *exec.Cmd { h := HelperProcessCommand{ Command: loop.PluginMercuryName, Limit: int(limit.Add(1)), } return h.New() - }, mercurytest.MercuryProvider, mercuryv4test.DataSource) + }, mercurytest.MercuryProvider(lggr), mercuryv4test.DataSource) servicetest.Run(t, mercury) mercurytest.MercuryPluginFactory(t, mercury) @@ -67,9 +69,10 @@ func TestMercuryV4Service_recovery(t *testing.T) { func TestMercuryV3Service(t *testing.T) { t.Parallel() - mercuryV3 := loop.NewMercuryV3Service(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + lggr := logger.Test(t) + mercuryV3 := loop.NewMercuryV3Service(lggr, loop.GRPCOpts{}, func() *exec.Cmd { return NewHelperProcessCommand(loop.PluginMercuryName, true, 0) - }, mercurytest.MercuryProvider, mercuryv3test.DataSource) + }, mercurytest.MercuryProvider(lggr), mercuryv3test.DataSource) hook := mercuryV3.PluginService.XXXTestHook() servicetest.Run(t, mercuryV3) @@ -98,14 +101,15 @@ func TestMercuryV3Service(t *testing.T) { func TestMercuryV3Service_recovery(t *testing.T) { t.Parallel() + lggr := logger.Test(t) var limit atomic.Int32 - mercury := loop.NewMercuryV3Service(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + mercury := loop.NewMercuryV3Service(lggr, loop.GRPCOpts{}, func() *exec.Cmd { h := HelperProcessCommand{ Command: loop.PluginMercuryName, Limit: int(limit.Add(1)), } return h.New() - }, mercurytest.MercuryProvider, mercuryv3test.DataSource) + }, mercurytest.MercuryProvider(lggr), mercuryv3test.DataSource) servicetest.Run(t, mercury) mercurytest.MercuryPluginFactory(t, mercury) @@ -114,9 +118,10 @@ func TestMercuryV3Service_recovery(t *testing.T) { func TestMercuryV1Service(t *testing.T) { t.Parallel() - mercuryV1 := loop.NewMercuryV1Service(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + lggr := logger.Test(t) + mercuryV1 := loop.NewMercuryV1Service(lggr, loop.GRPCOpts{}, func() *exec.Cmd { return NewHelperProcessCommand(loop.PluginMercuryName, true, 0) - }, mercurytest.MercuryProvider, mercuryv1test.DataSource) + }, mercurytest.MercuryProvider(lggr), mercuryv1test.DataSource) hook := mercuryV1.PluginService.XXXTestHook() servicetest.Run(t, mercuryV1) @@ -145,14 +150,15 @@ func TestMercuryV1Service(t *testing.T) { func TestMercuryV1Service_recovery(t *testing.T) { t.Parallel() + lggr := logger.Test(t) var limit atomic.Int32 - mercury := loop.NewMercuryV1Service(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + mercury := loop.NewMercuryV1Service(lggr, loop.GRPCOpts{}, func() *exec.Cmd { h := HelperProcessCommand{ Command: loop.PluginMercuryName, Limit: int(limit.Add(1)), } return h.New() - }, mercurytest.MercuryProvider, mercuryv1test.DataSource) + }, mercurytest.MercuryProvider(lggr), mercuryv1test.DataSource) servicetest.Run(t, mercury) mercurytest.MercuryPluginFactory(t, mercury) @@ -161,9 +167,10 @@ func TestMercuryV1Service_recovery(t *testing.T) { func TestMercuryV2Service(t *testing.T) { t.Parallel() - mercuryV2 := loop.NewMercuryV2Service(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + lggr := logger.Test(t) + mercuryV2 := loop.NewMercuryV2Service(lggr, loop.GRPCOpts{}, func() *exec.Cmd { return NewHelperProcessCommand(loop.PluginMercuryName, true, 0) - }, mercurytest.MercuryProvider, mercuryv2test.DataSource) + }, mercurytest.MercuryProvider(lggr), mercuryv2test.DataSource) hook := mercuryV2.PluginService.XXXTestHook() servicetest.Run(t, mercuryV2) @@ -192,14 +199,15 @@ func TestMercuryV2Service(t *testing.T) { func TestMercuryV2Service_recovery(t *testing.T) { t.Parallel() + lggr := logger.Test(t) var limit atomic.Int32 - mercury := loop.NewMercuryV2Service(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { + mercury := loop.NewMercuryV2Service(lggr, loop.GRPCOpts{}, func() *exec.Cmd { h := HelperProcessCommand{ Command: loop.PluginMercuryName, Limit: int(limit.Add(1)), } return h.New() - }, mercurytest.MercuryProvider, mercuryv2test.DataSource) + }, mercurytest.MercuryProvider(lggr), mercuryv2test.DataSource) servicetest.Run(t, mercury) mercurytest.MercuryPluginFactory(t, mercury) diff --git a/pkg/loop/plugin_median.go b/pkg/loop/plugin_median.go index d943c94be..f82784b66 100644 --- a/pkg/loop/plugin_median.go +++ b/pkg/loop/plugin_median.go @@ -41,6 +41,7 @@ type GRPCPluginMedian struct { } func (p *GRPCPluginMedian) GRPCServer(broker *plugin.GRPCBroker, server *grpc.Server) error { + //TODO when to start PluginServer return median.RegisterPluginMedianServer(server, broker, p.BrokerConfig, p.PluginServer) } diff --git a/pkg/loop/plugin_median_test.go b/pkg/loop/plugin_median_test.go index 90b617f51..41015ea66 100644 --- a/pkg/loop/plugin_median_test.go +++ b/pkg/loop/plugin_median_test.go @@ -24,25 +24,27 @@ func TestPluginMedian(t *testing.T) { stopCh := newStopCh(t) t.Run("no proxy", func(t *testing.T) { + lggr := logger.Test(t) test.PluginTest(t, loop.PluginMedianName, &loop.GRPCPluginMedian{ - PluginServer: mediantest.MedianFactoryServer, - BrokerConfig: loop.BrokerConfig{Logger: logger.Test(t), StopCh: stopCh}, + PluginServer: mediantest.NewMedianFactoryServer(lggr), + BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}, }, mediantest.PluginMedian) }) t.Run("proxy", func(t *testing.T) { + lggr := logger.Test(t) test.PluginTest(t, loop.PluginRelayerName, &loop.GRPCPluginRelayer{ - PluginServer: relayertest.NewRelayerTester(false), + PluginServer: relayertest.NewPluginRelayer(lggr, false), BrokerConfig: loop.BrokerConfig{Logger: logger.Test(t), StopCh: stopCh}}, func(t *testing.T, pr loop.PluginRelayer) { p := newMedianProvider(t, pr) pm := mediantest.PluginMedianTest{MedianProvider: p} test.PluginTest(t, loop.PluginMedianName, &loop.GRPCPluginMedian{ - PluginServer: mediantest.MedianFactoryServer, + PluginServer: mediantest.NewMedianFactoryServer(lggr), BrokerConfig: loop.BrokerConfig{Logger: logger.Test(t), StopCh: stopCh}}, pm.TestPluginMedian) }) diff --git a/pkg/loop/plugin_mercury_test.go b/pkg/loop/plugin_mercury_test.go index 36af7c35f..472a70c94 100644 --- a/pkg/loop/plugin_mercury_test.go +++ b/pkg/loop/plugin_mercury_test.go @@ -20,20 +20,21 @@ import ( func TestPluginMercury(t *testing.T) { t.Parallel() + lggr := logger.Test(t) stopCh := newStopCh(t) - test.PluginTest(t, loop.PluginMercuryName, &loop.GRPCPluginMercury{PluginServer: mercurytest.FactoryServer, BrokerConfig: loop.BrokerConfig{Logger: logger.Test(t), StopCh: stopCh}}, mercurytest.PluginMercury) + test.PluginTest(t, loop.PluginMercuryName, &loop.GRPCPluginMercury{PluginServer: mercurytest.FactoryServer(lggr), BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}}, mercurytest.PluginMercury) t.Run("proxy", func(t *testing.T) { test.PluginTest(t, loop.PluginRelayerName, &loop.GRPCPluginRelayer{ - PluginServer: relayertest.NewRelayerTester(false), - BrokerConfig: loop.BrokerConfig{Logger: logger.Test(t), StopCh: stopCh}}, + PluginServer: relayertest.NewPluginRelayer(lggr, false), + BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}}, func(t *testing.T, pr loop.PluginRelayer) { p := newMercuryProvider(t, pr) pm := mercurytest.PluginMercuryTest{MercuryProvider: p} test.PluginTest(t, loop.PluginMercuryName, - &loop.GRPCPluginMercury{PluginServer: mercurytest.FactoryServer, - BrokerConfig: loop.BrokerConfig{Logger: logger.Test(t), StopCh: stopCh}}, + &loop.GRPCPluginMercury{PluginServer: mercurytest.FactoryServer(lggr), + BrokerConfig: loop.BrokerConfig{Logger: lggr, StopCh: stopCh}}, pm.TestPluginMercury) }) }) diff --git a/pkg/loop/plugin_relayer.go b/pkg/loop/plugin_relayer.go index b4498650d..03c9b4d41 100644 --- a/pkg/loop/plugin_relayer.go +++ b/pkg/loop/plugin_relayer.go @@ -45,6 +45,7 @@ type GRPCPluginRelayer struct { } func (p *GRPCPluginRelayer) GRPCServer(broker *plugin.GRPCBroker, server *grpc.Server) error { + //TODO when to start PluginServer... auto? or explicit call from other side? return relayer.RegisterPluginRelayerServer(server, broker, p.BrokerConfig, p.PluginServer) } diff --git a/pkg/loop/plugin_relayer_test.go b/pkg/loop/plugin_relayer_test.go index f4471af5e..8ad918244 100644 --- a/pkg/loop/plugin_relayer_test.go +++ b/pkg/loop/plugin_relayer_test.go @@ -18,10 +18,11 @@ import ( func TestPluginRelayer(t *testing.T) { t.Parallel() + lggr := logger.Test(t) stopCh := newStopCh(t) test.PluginTest(t, loop.PluginRelayerName, &loop.GRPCPluginRelayer{ - PluginServer: relayertest.NewRelayerTester(false), + PluginServer: relayertest.NewPluginRelayer(lggr, false), BrokerConfig: loop.BrokerConfig{ Logger: logger.Test(t), StopCh: stopCh}}, diff --git a/pkg/loop/process_test.go b/pkg/loop/process_test.go index 2c8b2aa1f..81e21eba2 100644 --- a/pkg/loop/process_test.go +++ b/pkg/loop/process_test.go @@ -8,16 +8,15 @@ import ( type HelperProcessCommand test.HelperProcessCommand -func (h *HelperProcessCommand) New() *exec.Cmd { +func (h HelperProcessCommand) New() *exec.Cmd { h.CommandLocation = "./internal/test/cmd/main.go" - return (test.HelperProcessCommand)(*h).New() + return (test.HelperProcessCommand)(h).New() } func NewHelperProcessCommand(command string, staticChecks bool, throwErrorType int) *exec.Cmd { - h := HelperProcessCommand{ + return HelperProcessCommand{ Command: command, StaticChecks: staticChecks, ThrowErrorType: throwErrorType, - } - return h.New() + }.New() } diff --git a/pkg/loop/relayer_service.go b/pkg/loop/relayer_service.go index 7420854fa..b4054e117 100644 --- a/pkg/loop/relayer_service.go +++ b/pkg/loop/relayer_service.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/goplugin" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) @@ -22,16 +23,20 @@ type RelayerService struct { // NewRelayerService returns a new [*RelayerService]. // cmd must return a new exec.Cmd each time it is called. func NewRelayerService(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd, config string, keystore core.Keystore, capabilityRegistry core.CapabilitiesRegistry) *RelayerService { - newService := func(ctx context.Context, instance any) (Relayer, error) { + newService := func(ctx context.Context, instance any) (Relayer, services.HealthReporter, error) { plug, ok := instance.(PluginRelayer) if !ok { - return nil, fmt.Errorf("expected PluginRelayer but got %T", instance) + return nil, nil, fmt.Errorf("expected PluginRelayer but got %T", instance) + } + //TODo plug.Start(ctx)? (how to close?) + if err := plug.Start(ctx); err != nil { + return nil, nil, fmt.Errorf("failed to start PluginRelayer: %w", err) } r, err := plug.NewRelayer(ctx, config, keystore, capabilityRegistry) if err != nil { - return nil, fmt.Errorf("failed to create Relayer: %w", err) + return nil, nil, fmt.Errorf("failed to create Relayer: %w", err) } - return r, nil + return r, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "RelayerService") diff --git a/pkg/loop/relayer_service_test.go b/pkg/loop/relayer_service_test.go index 43327f6fb..1a8737174 100644 --- a/pkg/loop/relayer_service_test.go +++ b/pkg/loop/relayer_service_test.go @@ -2,11 +2,16 @@ package loop_test import ( "os/exec" + "strings" "sync/atomic" "testing" "time" "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + "golang.org/x/exp/maps" + "golang.org/x/exp/slices" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop" @@ -19,6 +24,16 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) +var relayerServiceNames = []string{ + "RelayerService", + "RelayerService.PluginRelayerClient", + "RelayerService.PluginRelayerClient.staticPluginRelayer", + "RelayerService.PluginRelayerClient.staticPluginRelayer.staticRelayer", + "RelayerService.PluginRelayerClient.staticPluginRelayer.staticRelayer.staticMedianProvider", + "RelayerService.PluginRelayerClient.staticPluginRelayer.staticRelayer.staticPluginProvider", + "RelayerService.PluginRelayerClient.staticPluginRelayer.staticRelayer.staticConfigProvider", +} + func TestRelayerService(t *testing.T) { t.Parallel() capRegistry := mocks.NewCapabilitiesRegistry(t) @@ -30,6 +45,7 @@ func TestRelayerService(t *testing.T) { t.Run("control", func(t *testing.T) { relayertest.Run(t, relayer) + servicetest.AssertHealthReportNames(t, relayer.HealthReport(), relayerServiceNames...) }) t.Run("Kill", func(t *testing.T) { @@ -39,6 +55,8 @@ func TestRelayerService(t *testing.T) { time.Sleep(2 * goplugin.KeepAliveTickDuration) relayertest.Run(t, relayer) + servicetest.AssertHealthReportNames(t, relayer.HealthReport(), relayerServiceNames...) + }) t.Run("Reset", func(t *testing.T) { @@ -48,6 +66,8 @@ func TestRelayerService(t *testing.T) { time.Sleep(2 * goplugin.KeepAliveTickDuration) relayertest.Run(t, relayer) + servicetest.AssertHealthReportNames(t, relayer.HealthReport(), relayerServiceNames...) + }) } @@ -55,34 +75,59 @@ func TestRelayerService_recovery(t *testing.T) { t.Parallel() var limit atomic.Int32 relayer := loop.NewRelayerService(logger.Test(t), loop.GRPCOpts{}, func() *exec.Cmd { - h := HelperProcessCommand{ + return HelperProcessCommand{ Command: loop.PluginRelayerName, Limit: int(limit.Add(1)), - } - return h.New() + }.New() }, test.ConfigTOML, keystoretest.Keystore, nil) servicetest.Run(t, relayer) relayertest.Run(t, relayer) + + servicetest.AssertHealthReportNames(t, relayer.HealthReport(), relayerServiceNames[:2]...) + } func TestRelayerService_HealthReport(t *testing.T) { - lggr := logger.Named(logger.Test(t), "Foo") + t.Parallel() + + lggr, obsLogs := logger.TestObserved(t, zapcore.DebugLevel) + t.Cleanup(AssertLogsObserved(t, obsLogs, relayerServiceNames)) //TODO but not all logging? Or with extra names in-between? capRegistry := mocks.NewCapabilitiesRegistry(t) s := loop.NewRelayerService(lggr, loop.GRPCOpts{}, func() *exec.Cmd { return test.HelperProcessCommand{Command: loop.PluginRelayerName}.New() }, test.ConfigTOML, keystoretest.Keystore, capRegistry) - servicetest.AssertHealthReportNames(t, s.HealthReport(), - "Foo.RelayerService") + servicetest.AssertHealthReportNames(t, s.HealthReport(), relayerServiceNames[0]) - require.NoError(t, s.Start(tests.Context(t))) - t.Cleanup(func() { require.NoError(t, s.Close()) }) + servicetest.Run(t, s) require.Eventually(t, func() bool { return s.Ready() == nil }, tests.WaitTimeout(t)/2, time.Second, s.Ready()) - servicetest.AssertHealthReportNames(t, s.HealthReport(), - "Foo.RelayerService", - "Foo.RelayerService.PluginRelayerClient.ChainRelayerClient", - "staticRelayer") + servicetest.AssertHealthReportNames(t, s.HealthReport(), relayerServiceNames...) + +} + +// TODO observed only or at least? +func AssertLogsObserved(t *testing.T, obsLogs *observer.ObservedLogs, names []string) func() { + return func() { + t.Helper() + + obsNames := map[string]struct{}{} + for _, l := range obsLogs.All() { + obsNames[l.LoggerName] = struct{}{} + } + var failed bool + for _, n := range names { + if _, ok := obsNames[n]; !ok { + t.Errorf("No logs observed for service: %s", n) + failed = true + } + } + if failed { + keys := maps.Keys(obsNames) + slices.Sort(keys) + t.Logf("Loggers observed:\n%s\n", strings.Join(keys, "\n")) + } + } } diff --git a/pkg/loop/reportingplugins/grpc.go b/pkg/loop/reportingplugins/grpc.go index 57475063b..d86025b8b 100644 --- a/pkg/loop/reportingplugins/grpc.go +++ b/pkg/loop/reportingplugins/grpc.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/median" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ext/ocr3capability" pluginprovider "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ocr2" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) @@ -61,6 +62,7 @@ type serverAdapter struct { } type ValidateConfigService interface { + services.Service NewValidationService(ctx context.Context) (core.ValidationService, error) } diff --git a/pkg/loop/reportingplugins/grpc_test.go b/pkg/loop/reportingplugins/grpc_test.go index 32aff7181..e58c999fe 100644 --- a/pkg/loop/reportingplugins/grpc_test.go +++ b/pkg/loop/reportingplugins/grpc_test.go @@ -60,14 +60,15 @@ func PluginGenericTest(t *testing.T, p core.ReportingPluginClient) { func TestGRPCService_MedianProvider(t *testing.T) { t.Parallel() + lggr := logger.Test(t) stopCh := newStopCh(t) test.PluginTest( t, ocr2test.MedianID, &reportingplugins.GRPCService[types.MedianProvider]{ - PluginServer: ocr2test.MedianProviderServer, + PluginServer: ocr2test.MedianProviderServer(lggr), BrokerConfig: loop.BrokerConfig{ - Logger: logger.Test(t), + Logger: lggr, StopCh: stopCh, }, }, @@ -78,14 +79,15 @@ func TestGRPCService_MedianProvider(t *testing.T) { func TestGRPCService_PluginProvider(t *testing.T) { t.Parallel() + lggr := logger.Test(t) stopCh := newStopCh(t) test.PluginTest( t, reportingplugins.PluginServiceName, &reportingplugins.GRPCService[types.PluginProvider]{ - PluginServer: ocr2test.AgnosticProviderServer, + PluginServer: ocr2test.AgnosticProviderServer(lggr), BrokerConfig: loop.BrokerConfig{ - Logger: logger.Test(t), + Logger: lggr, StopCh: stopCh, }, }, diff --git a/pkg/loop/reportingplugins/loopp_service.go b/pkg/loop/reportingplugins/loopp_service.go index 8fbbaa68c..81e583494 100644 --- a/pkg/loop/reportingplugins/loopp_service.go +++ b/pkg/loop/reportingplugins/loopp_service.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/goplugin" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/net" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) @@ -43,13 +44,18 @@ func NewLOOPPService( keyValueStore core.KeyValueStore, relayerSet core.RelayerSet, ) *LOOPPService { - newService := func(ctx context.Context, instance any) (types.ReportingPluginFactory, error) { + newService := func(ctx context.Context, instance any) (types.ReportingPluginFactory, services.HealthReporter, error) { plug, ok := instance.(core.ReportingPluginClient) if !ok { - return nil, fmt.Errorf("expected GenericPluginClient but got %T", instance) + return nil, nil, fmt.Errorf("expected GenericPluginClient but got %T", instance) } - return plug.NewReportingPluginFactory(ctx, config, providerConn, pipelineRunner, telemetryService, errorLog, keyValueStore, + //TODo plug.Start(ctx)? (how to close?) + factory, err := plug.NewReportingPluginFactory(ctx, config, providerConn, pipelineRunner, telemetryService, errorLog, keyValueStore, relayerSet) + if err != nil { + return nil, nil, err + } + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "GenericService") @@ -71,12 +77,16 @@ func NewLOOPPServiceValidation( grpcOpts loop.GRPCOpts, cmd func() *exec.Cmd, ) *LOOPPServiceValidation { - newService := func(ctx context.Context, instance any) (core.ValidationService, error) { + newService := func(ctx context.Context, instance any) (core.ValidationService, services.HealthReporter, error) { plug, ok := instance.(core.ReportingPluginClient) if !ok { - return nil, fmt.Errorf("expected ValidationServiceClient but got %T", instance) + return nil, nil, fmt.Errorf("expected ValidationServiceClient but got %T", instance) + } + srv, err := plug.NewValidationService(ctx) + if err != nil { + return nil, nil, err } - return plug.NewValidationService(ctx) + return srv, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "GenericService") diff --git a/pkg/loop/reportingplugins/ocr3/grpc.go b/pkg/loop/reportingplugins/ocr3/grpc.go index c7d4ca68c..8ebc639df 100644 --- a/pkg/loop/reportingplugins/ocr3/grpc.go +++ b/pkg/loop/reportingplugins/ocr3/grpc.go @@ -11,6 +11,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/core/services/telemetry" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/net" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) @@ -49,6 +50,7 @@ type serverAdapter struct { } type ValidateConfigService interface { + services.Service NewValidationService(ctx context.Context) (core.ValidationService, error) } diff --git a/pkg/loop/reportingplugins/ocr3/grpc_test.go b/pkg/loop/reportingplugins/ocr3/grpc_test.go index 60b6532d5..f348f2230 100644 --- a/pkg/loop/reportingplugins/ocr3/grpc_test.go +++ b/pkg/loop/reportingplugins/ocr3/grpc_test.go @@ -59,14 +59,15 @@ func PluginGenericTest(t *testing.T, p core.OCR3ReportingPluginClient) { func TestGRPCService_MedianProvider(t *testing.T) { t.Parallel() + lggr := logger.Test(t) stopCh := newStopCh(t) test.PluginTest( t, ocr3test.OCR3ReportingPluginWithMedianProviderName, &GRPCService[types.MedianProvider]{ - PluginServer: ocr3test.MedianServer, + PluginServer: ocr3test.MedianServer(lggr), BrokerConfig: loop.BrokerConfig{ - Logger: logger.Test(t), + Logger: lggr, StopCh: stopCh, }, }, @@ -77,12 +78,13 @@ func TestGRPCService_MedianProvider(t *testing.T) { func TestGRPCService_PluginProvider(t *testing.T) { t.Parallel() + lggr := logger.Test(t) stopCh := newStopCh(t) test.PluginTest( t, PluginServiceName, &GRPCService[types.PluginProvider]{ - PluginServer: ocr3test.AgnosticPluginServer, + PluginServer: ocr3test.AgnosticPluginServer(lggr), BrokerConfig: loop.BrokerConfig{ Logger: logger.Test(t), StopCh: stopCh, diff --git a/pkg/loop/reportingplugins/ocr3/loopp_service.go b/pkg/loop/reportingplugins/ocr3/loopp_service.go index 7b10fcabc..d9c1b2765 100644 --- a/pkg/loop/reportingplugins/ocr3/loopp_service.go +++ b/pkg/loop/reportingplugins/ocr3/loopp_service.go @@ -14,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/goplugin" "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/net" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) @@ -35,12 +36,16 @@ func NewLOOPPService( keyValueStore core.KeyValueStore, relayerSet core.RelayerSet, ) *LOOPPService { - newService := func(ctx context.Context, instance any) (core.OCR3ReportingPluginFactory, error) { + newService := func(ctx context.Context, instance any) (core.OCR3ReportingPluginFactory, services.HealthReporter, error) { plug, ok := instance.(core.OCR3ReportingPluginClient) if !ok { - return nil, fmt.Errorf("expected OCR3ReportingPluginClient but got %T", instance) + return nil, nil, fmt.Errorf("expected OCR3ReportingPluginClient but got %T", instance) } - return plug.NewReportingPluginFactory(ctx, config, providerConn, pipelineRunner, telemetryService, errorLog, capRegistry, keyValueStore, relayerSet) + factory, err := plug.NewReportingPluginFactory(ctx, config, providerConn, pipelineRunner, telemetryService, errorLog, capRegistry, keyValueStore, relayerSet) + if err != nil { + return nil, nil, err + } + return factory, plug, nil } stopCh := make(chan struct{}) @@ -63,12 +68,16 @@ func NewLOOPPServiceValidation( grpcOpts loop.GRPCOpts, cmd func() *exec.Cmd, ) *reportingplugins.LOOPPServiceValidation { - newService := func(ctx context.Context, instance any) (core.ValidationService, error) { + newService := func(ctx context.Context, instance any) (core.ValidationService, services.HealthReporter, error) { plug, ok := instance.(core.OCR3ReportingPluginClient) if !ok { - return nil, fmt.Errorf("expected ValidationServiceClient but got %T", instance) + return nil, nil, fmt.Errorf("expected ValidationServiceClient but got %T", instance) + } + factory, err := plug.NewValidationService(ctx) + if err != nil { + return nil, nil, err } - return plug.NewValidationService(ctx) + return factory, plug, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "GenericService") diff --git a/pkg/loop/standard_capabilities.go b/pkg/loop/standard_capabilities.go index aab781c1d..5b974744f 100644 --- a/pkg/loop/standard_capabilities.go +++ b/pkg/loop/standard_capabilities.go @@ -82,12 +82,12 @@ type StandardCapabilitiesService struct { } func NewStandardCapabilitiesService(lggr logger.Logger, grpcOpts GRPCOpts, cmd func() *exec.Cmd) *StandardCapabilitiesService { - newService := func(ctx context.Context, instance any) (StandardCapabilities, error) { + newService := func(ctx context.Context, instance any) (StandardCapabilities, services.HealthReporter, error) { scs, ok := instance.(StandardCapabilities) if !ok { - return nil, fmt.Errorf("expected StandardCapabilities but got %T", instance) + return nil, nil, fmt.Errorf("expected StandardCapabilities but got %T", instance) } - return scs, nil + return scs, scs, nil } stopCh := make(chan struct{}) lggr = logger.Named(lggr, "StandardCapabilities") diff --git a/pkg/services/servicetest/health.go b/pkg/services/servicetest/health.go index b43e0fe6e..fd84a1877 100644 --- a/pkg/services/servicetest/health.go +++ b/pkg/services/servicetest/health.go @@ -1,6 +1,7 @@ package servicetest import ( + "strings" "testing" "github.com/stretchr/testify/assert" @@ -13,5 +14,6 @@ func AssertHealthReportNames(t *testing.T, hp map[string]error, names ...string) keys := maps.Keys(hp) slices.Sort(keys) slices.Sort(names) - assert.EqualValues(t, names, keys) + join := func(s []string) string { return strings.Join(s, "\n") } + assert.Equal(t, join(names), join(keys)) } diff --git a/pkg/services/servicetest/run.go b/pkg/services/servicetest/run.go index 8a1046e3c..4086682bb 100644 --- a/pkg/services/servicetest/run.go +++ b/pkg/services/servicetest/run.go @@ -27,8 +27,8 @@ type TestingT interface { // Run fails tb if the service fails to start or close. func Run[R Runnable](tb TestingT, r R) R { tb.Helper() - require.NoError(tb, r.Start(tests.Context(tb)), "service failed to start") - tb.Cleanup(func() { assert.NoError(tb, r.Close(), "error closing service") }) + require.NoError(tb, r.Start(tests.Context(tb)), "service failed to start: %T", r) + tb.Cleanup(func() { assert.NoError(tb, r.Close(), "error closing service: %T", r) }) return r } diff --git a/pkg/types/contract_reader.go b/pkg/types/contract_reader.go index 9cf6b0555..91fd99bb4 100644 --- a/pkg/types/contract_reader.go +++ b/pkg/types/contract_reader.go @@ -162,11 +162,11 @@ func (UnimplementedContractReader) Close() error { } func (UnimplementedContractReader) HealthReport() map[string]error { - panic(UnimplementedError("ContractReader.HealthReport unimplemented")) + return map[string]error{"UnimplementedContractReader": UnimplementedError("ContractReader.HealthReport unimplemented")} } func (UnimplementedContractReader) Name() string { - panic(UnimplementedError("ContractReader.Name unimplemented")) + return "UnimplementedContractReader" } func (UnimplementedContractReader) Ready() error { diff --git a/pkg/types/core/median.go b/pkg/types/core/median.go index 14e6fc866..574b02a6a 100644 --- a/pkg/types/core/median.go +++ b/pkg/types/core/median.go @@ -5,10 +5,12 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" ) type PluginMedian interface { + services.Service // NewMedianFactory returns a new ReportingPluginFactory. If provider implements GRPCClientConn, it can be forwarded efficiently via proxy. NewMedianFactory(ctx context.Context, provider types.MedianProvider, contractID string, dataSource, juelsPerFeeCoin, gasPriceSubunits median.DataSource, errorLog ErrorLog) (types.ReportingPluginFactory, error) } diff --git a/pkg/types/core/reporting_plugin_service.go b/pkg/types/core/reporting_plugin_service.go index 39dd444a1..43fe40ede 100644 --- a/pkg/types/core/reporting_plugin_service.go +++ b/pkg/types/core/reporting_plugin_service.go @@ -22,6 +22,7 @@ type ReportingPluginServiceConfig struct { // ReportingPluginClient is the client interface to a plugin running // as a generic job (job type = GenericPlugin) inside the core node. type ReportingPluginClient interface { + services.Service NewReportingPluginFactory(ctx context.Context, config ReportingPluginServiceConfig, grpcProvider grpc.ClientConnInterface, pipelineRunner PipelineRunnerService, telemetry TelemetryService, errorLog ErrorLog, keyValueStore KeyValueStore, relayerSet RelayerSet) (types.ReportingPluginFactory, error) NewValidationService(ctx context.Context) (ValidationService, error) } @@ -31,16 +32,19 @@ type ReportingPluginClient interface { // with the passthrough provider connection converted to the provider // expected by the plugin. type ReportingPluginServer[T types.PluginProvider] interface { + services.Service NewReportingPluginFactory(ctx context.Context, config ReportingPluginServiceConfig, provider T, pipelineRunner PipelineRunnerService, telemetry TelemetryClient, errorLog ErrorLog, keyValueStore KeyValueStore, relayerSet RelayerSet) (types.ReportingPluginFactory, error) NewValidationService(ctx context.Context) (ValidationService, error) } type OCR3ReportingPluginClient interface { + services.Service NewReportingPluginFactory(ctx context.Context, config ReportingPluginServiceConfig, grpcProvider grpc.ClientConnInterface, pipelineRunner PipelineRunnerService, telemetry TelemetryService, errorLog ErrorLog, capRegistry CapabilitiesRegistry, keyValueStore KeyValueStore, relayerSet RelayerSet) (OCR3ReportingPluginFactory, error) NewValidationService(ctx context.Context) (ValidationService, error) } type OCR3ReportingPluginServer[T types.PluginProvider] interface { + services.Service NewReportingPluginFactory(ctx context.Context, config ReportingPluginServiceConfig, provider T, pipelineRunner PipelineRunnerService, telemetry TelemetryClient, errorLog ErrorLog, capRegistry CapabilitiesRegistry, keyValueStore KeyValueStore, relayerSet RelayerSet) (OCR3ReportingPluginFactory, error) NewValidationService(ctx context.Context) (ValidationService, error) } diff --git a/pkg/types/provider_ccip.go b/pkg/types/provider_ccip.go index 3ba9cde02..426cdaa2b 100644 --- a/pkg/types/provider_ccip.go +++ b/pkg/types/provider_ccip.go @@ -3,6 +3,7 @@ package types import ( "context" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" ) @@ -31,10 +32,12 @@ type CCIPExecProvider interface { } type CCIPCommitFactoryGenerator interface { + services.Service NewCommitFactory(ctx context.Context, provider CCIPCommitProvider) (ReportingPluginFactory, error) } type CCIPExecutionFactoryGenerator interface { + services.Service NewExecutionFactory(ctx context.Context, srcProvider CCIPExecProvider, dstProvider CCIPExecProvider, srcChainID int64, dstChainID int64, sourceTokenAddress string) (ReportingPluginFactory, error) } type CCIPFactoryGenerator interface { diff --git a/pkg/types/provider_mercury.go b/pkg/types/provider_mercury.go index 0c558aaf3..4e89aa710 100644 --- a/pkg/types/provider_mercury.go +++ b/pkg/types/provider_mercury.go @@ -5,6 +5,7 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" @@ -27,6 +28,7 @@ type MercuryProvider interface { } type PluginMercury interface { + services.Service NewMercuryV1Factory(ctx context.Context, provider MercuryProvider, dataSource v1.DataSource) (MercuryPluginFactory, error) NewMercuryV2Factory(ctx context.Context, provider MercuryProvider, dataSource v2.DataSource) (MercuryPluginFactory, error) NewMercuryV3Factory(ctx context.Context, provider MercuryProvider, dataSource v3.DataSource) (MercuryPluginFactory, error)