From 62c3acb7fa2ce9ecc630e92715b84cbc0ba3d81a Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Fri, 21 Jun 2024 11:35:25 +0100 Subject: [PATCH 01/21] feat(oti-head-report): Report new heads to atlas' OTI --- core/services/chainlink/application.go | 8 +- core/services/headreporter/head_reporter.go | 106 ++++++++++ .../head_reporter_test.go} | 10 +- .../prometheus_reporter.go} | 166 +++++---------- .../headreporter/telemetry_reporter.go | 53 +++++ core/services/synchronization/common.go | 1 + .../telem/telem_head_report.pb.go | 194 ++++++++++++++++++ .../telem/telem_head_report.proto | 13 ++ 8 files changed, 426 insertions(+), 125 deletions(-) create mode 100644 core/services/headreporter/head_reporter.go rename core/services/{promreporter/prom_reporter_test.go => headreporter/head_reporter_test.go} (95%) rename core/services/{promreporter/prom_reporter.go => headreporter/prometheus_reporter.go} (67%) create mode 100644 core/services/headreporter/telemetry_reporter.go create mode 100644 core/services/synchronization/telem/telem_head_report.pb.go create mode 100644 core/services/synchronization/telem/telem_head_report.proto diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 17c217b1c90..6649b4fc6c8 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -45,6 +45,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/feeds" "github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2" "github.com/smartcontractkit/chainlink/v2/core/services/gateway" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -56,7 +57,6 @@ import ( externalp2p "github.com/smartcontractkit/chainlink/v2/core/services/p2p/wrapper" "github.com/smartcontractkit/chainlink/v2/core/services/periodicbackup" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/promreporter" "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" @@ -323,8 +323,8 @@ func NewApplication(opts ApplicationOpts) (Application, error) { srvcs = append(srvcs, mailMon) srvcs = append(srvcs, relayerChainInterops.Services()...) - promReporter := promreporter.NewPromReporter(opts.DS, legacyEVMChains, globalLogger) - srvcs = append(srvcs, promReporter) + headReporter := headreporter.NewHeadReporter(opts.DS, legacyEVMChains, globalLogger) + srvcs = append(srvcs, headReporter) // Initialize Local Users ORM and Authentication Provider specified in config // BasicAdminUsersORM is initialized and required regardless of separate Authentication Provider @@ -365,7 +365,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { ) for _, chain := range legacyEVMChains.Slice() { - chain.HeadBroadcaster().Subscribe(promReporter) + chain.HeadBroadcaster().Subscribe(headReporter) chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun) } diff --git a/core/services/headreporter/head_reporter.go b/core/services/headreporter/head_reporter.go new file mode 100644 index 00000000000..2dbd7890a3b --- /dev/null +++ b/core/services/headreporter/head_reporter.go @@ -0,0 +1,106 @@ +package headreporter + +import ( + "context" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "sync" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +//go:generate mockery --quiet --name PrometheusBackend --output ../../internal/mocks/ --case=underscore +type ( + Reporter interface { + reportOnHead(ctx context.Context, head *evmtypes.Head) + reportPeriodic(ctx context.Context) + } + + headReporter struct { + services.StateMachine + ds sqlutil.DataSource + chains legacyevm.LegacyChainContainer + lggr logger.Logger + newHeads *mailbox.Mailbox[*evmtypes.Head] + chStop services.StopChan + wgDone sync.WaitGroup + reportPeriod time.Duration + reporters []Reporter + } +) + +var ( + name = "HeadReporter" +) + +func NewHeadReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *headReporter { + chStop := make(chan struct{}) + return &headReporter{ + ds: ds, + chains: chainContainer, + lggr: lggr.Named(name), + newHeads: mailbox.NewSingle[*evmtypes.Head](), + chStop: chStop, + reporters: []Reporter{ + NewPrometheusReporter(ds, chainContainer, lggr, opts), + NewTelemetryReporter(chainContainer, lggr), + }, + } +} + +func (rr *headReporter) Start(context.Context) error { + return rr.StartOnce(name, func() error { + rr.wgDone.Add(1) + go rr.eventLoop() + return nil + }) +} + +func (rr *headReporter) Close() error { + return rr.StopOnce(name, func() error { + close(rr.chStop) + rr.wgDone.Wait() + return nil + }) +} +func (rr *headReporter) Name() string { + return rr.lggr.Name() +} + +func (rr *headReporter) HealthReport() map[string]error { + return map[string]error{rr.Name(): rr.Healthy()} +} + +func (rr *headReporter) OnNewLongestChain(ctx context.Context, head *evmtypes.Head) { + rr.newHeads.Deliver(head) +} + +func (rr *headReporter) eventLoop() { + rr.lggr.Debug("Starting event loop") + defer rr.wgDone.Done() + ctx, cancel := rr.chStop.NewCtx() + defer cancel() + for { + select { + case <-rr.newHeads.Notify(): + head, exists := rr.newHeads.Retrieve() + if !exists { + continue + } + for _, reporter := range rr.reporters { + reporter.reportOnHead(ctx, head) + } + case <-time.After(rr.reportPeriod): + for _, reporter := range rr.reporters { + reporter.reportPeriodic(ctx) + } + case <-rr.chStop: + return + } + } +} diff --git a/core/services/promreporter/prom_reporter_test.go b/core/services/headreporter/head_reporter_test.go similarity index 95% rename from core/services/promreporter/prom_reporter_test.go rename to core/services/headreporter/head_reporter_test.go index a0a4a247c21..2383f60be50 100644 --- a/core/services/promreporter/prom_reporter_test.go +++ b/core/services/headreporter/head_reporter_test.go @@ -1,4 +1,4 @@ -package promreporter_test +package headreporter_test import ( "math/big" @@ -26,7 +26,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/promreporter" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" ) func newHead() evmtypes.Head { @@ -75,7 +75,7 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) { db := pgtest.NewSqlxDB(t) backend := mocks.NewPrometheusBackend(t) - reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) + reporter := headreporter.NewHeadReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) var subscribeCalls atomic.Int32 @@ -117,7 +117,7 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) { subscribeCalls.Add(1) }). Return() - reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) + reporter := headreporter.NewHeadReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) servicetest.Run(t, reporter) etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) @@ -136,7 +136,7 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) { pgtest.MustExec(t, db, `SET CONSTRAINTS pipeline_task_runs_pipeline_run_id_fkey DEFERRED`) backend := mocks.NewPrometheusBackend(t) - reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) + reporter := headreporter.NewHeadReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) diff --git a/core/services/promreporter/prom_reporter.go b/core/services/headreporter/prometheus_reporter.go similarity index 67% rename from core/services/promreporter/prom_reporter.go rename to core/services/headreporter/prometheus_reporter.go index 31d5f1129ef..7ad4965cfc9 100644 --- a/core/services/promreporter/prom_reporter.go +++ b/core/services/headreporter/prometheus_reporter.go @@ -1,40 +1,28 @@ -package promreporter +package headreporter import ( "context" "fmt" - "math/big" - "sync" - "time" - - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "go.uber.org/multierr" - - "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" + "go.uber.org/multierr" + "math/big" + "time" ) type ( - promReporter struct { - services.StateMachine - ds sqlutil.DataSource - chains legacyevm.LegacyChainContainer - lggr logger.Logger - backend PrometheusBackend - newHeads *mailbox.Mailbox[*evmtypes.Head] - chStop services.StopChan - wgDone sync.WaitGroup - reportPeriod time.Duration + prometheusReporter struct { + ds sqlutil.DataSource + chains legacyevm.LegacyChainContainer + lggr logger.Logger + backend PrometheusBackend } PrometheusBackend interface { @@ -71,103 +59,23 @@ var ( }) ) -func (defaultBackend) SetUnconfirmedTransactions(evmChainID *big.Int, n int64) { - promUnconfirmedTransactions.WithLabelValues(evmChainID.String()).Set(float64(n)) -} - -func (defaultBackend) SetMaxUnconfirmedAge(evmChainID *big.Int, s float64) { - promMaxUnconfirmedAge.WithLabelValues(evmChainID.String()).Set(s) -} - -func (defaultBackend) SetMaxUnconfirmedBlocks(evmChainID *big.Int, n int64) { - promMaxUnconfirmedBlocks.WithLabelValues(evmChainID.String()).Set(float64(n)) -} - -func (defaultBackend) SetPipelineRunsQueued(n int) { - promPipelineTaskRunsQueued.Set(float64(n)) -} - -func (defaultBackend) SetPipelineTaskRunsQueued(n int) { - promPipelineRunsQueued.Set(float64(n)) -} - -func NewPromReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *promReporter { +func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *prometheusReporter { var backend PrometheusBackend = defaultBackend{} - period := 15 * time.Second for _, opt := range opts { switch v := opt.(type) { - case time.Duration: - period = v case PrometheusBackend: backend = v } } - - chStop := make(chan struct{}) - return &promReporter{ - ds: ds, - chains: chainContainer, - lggr: lggr.Named("PromReporter"), - backend: backend, - newHeads: mailbox.NewSingle[*evmtypes.Head](), - chStop: chStop, - reportPeriod: period, + return &prometheusReporter{ + ds: ds, + chains: chainContainer, + lggr: lggr.Named(name), + backend: backend, } } -// Start starts PromReporter. -func (pr *promReporter) Start(context.Context) error { - return pr.StartOnce("PromReporter", func() error { - pr.wgDone.Add(1) - go pr.eventLoop() - return nil - }) -} - -func (pr *promReporter) Close() error { - return pr.StopOnce("PromReporter", func() error { - close(pr.chStop) - pr.wgDone.Wait() - return nil - }) -} -func (pr *promReporter) Name() string { - return pr.lggr.Name() -} - -func (pr *promReporter) HealthReport() map[string]error { - return map[string]error{pr.Name(): pr.Healthy()} -} - -func (pr *promReporter) OnNewLongestChain(ctx context.Context, head *evmtypes.Head) { - pr.newHeads.Deliver(head) -} - -func (pr *promReporter) eventLoop() { - pr.lggr.Debug("Starting event loop") - defer pr.wgDone.Done() - ctx, cancel := pr.chStop.NewCtx() - defer cancel() - for { - select { - case <-pr.newHeads.Notify(): - head, exists := pr.newHeads.Retrieve() - if !exists { - continue - } - pr.reportHeadMetrics(ctx, head) - case <-time.After(pr.reportPeriod): - if err := errors.Wrap(pr.reportPipelineRunStats(ctx), "reportPipelineRunStats failed"); err != nil { - pr.lggr.Errorw("Error reporting prometheus metrics", "err", err) - } - - case <-pr.chStop: - return - } - } -} - -func (pr *promReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, error) { +func (pr *prometheusReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, error) { chain, err := pr.chains.Get(evmChainID.String()) if err != nil { return nil, fmt.Errorf("failed to get chain: %w", err) @@ -175,7 +83,7 @@ func (pr *promReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, error) { return chain.TxManager(), nil } -func (pr *promReporter) reportHeadMetrics(ctx context.Context, head *evmtypes.Head) { +func (pr *prometheusReporter) reportOnHead(ctx context.Context, head *evmtypes.Head) { evmChainID := head.EVMChainID.ToInt() err := multierr.Combine( errors.Wrap(pr.reportPendingEthTxes(ctx, evmChainID), "reportPendingEthTxes failed"), @@ -188,7 +96,7 @@ func (pr *promReporter) reportHeadMetrics(ctx context.Context, head *evmtypes.He } } -func (pr *promReporter) reportPendingEthTxes(ctx context.Context, evmChainID *big.Int) (err error) { +func (pr *prometheusReporter) reportPendingEthTxes(ctx context.Context, evmChainID *big.Int) (err error) { txm, err := pr.getTxm(evmChainID) if err != nil { return fmt.Errorf("failed to get txm: %w", err) @@ -202,7 +110,7 @@ func (pr *promReporter) reportPendingEthTxes(ctx context.Context, evmChainID *bi return nil } -func (pr *promReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID *big.Int) (err error) { +func (pr *prometheusReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID *big.Int) (err error) { txm, err := pr.getTxm(evmChainID) if err != nil { return fmt.Errorf("failed to get txm: %w", err) @@ -221,7 +129,7 @@ func (pr *promReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID return nil } -func (pr *promReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *evmtypes.Head) (err error) { +func (pr *prometheusReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *evmtypes.Head) (err error) { txm, err := pr.getTxm(head.EVMChainID.ToInt()) if err != nil { return fmt.Errorf("failed to get txm: %w", err) @@ -240,7 +148,13 @@ func (pr *promReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *ev return nil } -func (pr *promReporter) reportPipelineRunStats(ctx context.Context) (err error) { +func (pr *prometheusReporter) reportPeriodic(ctx context.Context) { + if err := errors.Wrap(pr.reportPipelineRunStats(ctx), "reportPipelineRunStats failed"); err != nil { + pr.lggr.Errorw("Error reporting prometheus metrics", "err", err) + } +} + +func (pr *prometheusReporter) reportPipelineRunStats(ctx context.Context) (err error) { rows, err := pr.ds.QueryContext(ctx, ` SELECT pipeline_run_id FROM pipeline_task_runs WHERE finished_at IS NULL `) @@ -271,3 +185,23 @@ SELECT pipeline_run_id FROM pipeline_task_runs WHERE finished_at IS NULL return nil } + +func (defaultBackend) SetUnconfirmedTransactions(evmChainID *big.Int, n int64) { + promUnconfirmedTransactions.WithLabelValues(evmChainID.String()).Set(float64(n)) +} + +func (defaultBackend) SetMaxUnconfirmedAge(evmChainID *big.Int, s float64) { + promMaxUnconfirmedAge.WithLabelValues(evmChainID.String()).Set(s) +} + +func (defaultBackend) SetMaxUnconfirmedBlocks(evmChainID *big.Int, n int64) { + promMaxUnconfirmedBlocks.WithLabelValues(evmChainID.String()).Set(float64(n)) +} + +func (defaultBackend) SetPipelineRunsQueued(n int) { + promPipelineTaskRunsQueued.Set(float64(n)) +} + +func (defaultBackend) SetPipelineTaskRunsQueued(n int) { + promPipelineRunsQueued.Set(float64(n)) +} diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go new file mode 100644 index 00000000000..bceaa18fd76 --- /dev/null +++ b/core/services/headreporter/telemetry_reporter.go @@ -0,0 +1,53 @@ +package headreporter + +import ( + "context" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + "github.com/smartcontractkit/libocr/commontypes" + "google.golang.org/protobuf/proto" + "math/big" +) + +type ( + telemetryReporter struct { + logger logger.Logger + endpoints map[*big.Int]commontypes.MonitoringEndpoint + } +) + +func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) *telemetryReporter { + endpoints := make(map[*big.Int]commontypes.MonitoringEndpoint) + for _, chain := range chainContainer.Slice() { + endpoints[chain.ID()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chain.ID().String(), "", synchronization.HeadReport) + } + return &telemetryReporter{ + logger: lggr, + endpoints: endpoints, + } +} + +func (t *telemetryReporter) reportOnHead(ctx context.Context, head *evmtypes.Head) { + monitoringEndpoint := t.endpoints[head.EVMChainID.ToInt()] + request := &telem.HeadReportRequest{ + ChainId: head.EVMChainID.String(), + Timestamp: uint64(head.Timestamp.UTC().Unix()), + BlockNumber: uint64(head.Number), + BlockHash: head.Hash.Hex(), + Finalized: head.IsFinalized, + } + bytes, err := proto.Marshal(request) + if err != nil { + t.logger.Warnw("telem.HeadReportRequest marshal error", "err", err) + return + } + monitoringEndpoint.SendLog(bytes) +} + +func (t *telemetryReporter) reportPeriodic(ctx context.Context) { + //do nothing +} diff --git a/core/services/synchronization/common.go b/core/services/synchronization/common.go index 394830a76af..a6c0191e3a7 100644 --- a/core/services/synchronization/common.go +++ b/core/services/synchronization/common.go @@ -28,6 +28,7 @@ const ( OCR3CCIPCommit TelemetryType = "ocr3-ccip-commit" OCR3CCIPExec TelemetryType = "ocr3-ccip-exec" OCR3CCIPBootstrap TelemetryType = "ocr3-bootstrap" + HeadReport TelemetryType = "head-report" ) type TelemPayload struct { diff --git a/core/services/synchronization/telem/telem_head_report.pb.go b/core/services/synchronization/telem/telem_head_report.pb.go new file mode 100644 index 00000000000..24d4ddd7ae8 --- /dev/null +++ b/core/services/synchronization/telem/telem_head_report.pb.go @@ -0,0 +1,194 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v5.27.1 +// source: core/services/synchronization/telem/telem_head_report.proto + +package telem + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type HeadReportRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + Node string `protobuf:"bytes,2,opt,name=node,proto3" json:"node,omitempty"` + Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + BlockNumber uint64 `protobuf:"varint,4,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + BlockHash string `protobuf:"bytes,5,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + Finalized bool `protobuf:"varint,6,opt,name=finalized,proto3" json:"finalized,omitempty"` +} + +func (x *HeadReportRequest) Reset() { + *x = HeadReportRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HeadReportRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HeadReportRequest) ProtoMessage() {} + +func (x *HeadReportRequest) ProtoReflect() protoreflect.Message { + mi := &file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HeadReportRequest.ProtoReflect.Descriptor instead. +func (*HeadReportRequest) Descriptor() ([]byte, []int) { + return file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZIP(), []int{0} +} + +func (x *HeadReportRequest) GetChainId() string { + if x != nil { + return x.ChainId + } + return "" +} + +func (x *HeadReportRequest) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *HeadReportRequest) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *HeadReportRequest) GetBlockNumber() uint64 { + if x != nil { + return x.BlockNumber + } + return 0 +} + +func (x *HeadReportRequest) GetBlockHash() string { + if x != nil { + return x.BlockHash + } + return "" +} + +func (x *HeadReportRequest) GetFinalized() bool { + if x != nil { + return x.Finalized + } + return false +} + +var File_core_services_synchronization_telem_telem_head_report_proto protoreflect.FileDescriptor + +var file_core_services_synchronization_telem_telem_head_report_proto_rawDesc = []byte{ + 0x0a, 0x3b, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, + 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x68, 0x65, 0x61, 0x64, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x22, 0xc0, 0x01, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x3b, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_core_services_synchronization_telem_telem_head_report_proto_rawDescOnce sync.Once + file_core_services_synchronization_telem_telem_head_report_proto_rawDescData = file_core_services_synchronization_telem_telem_head_report_proto_rawDesc +) + +func file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZIP() []byte { + file_core_services_synchronization_telem_telem_head_report_proto_rawDescOnce.Do(func() { + file_core_services_synchronization_telem_telem_head_report_proto_rawDescData = protoimpl.X.CompressGZIP(file_core_services_synchronization_telem_telem_head_report_proto_rawDescData) + }) + return file_core_services_synchronization_telem_telem_head_report_proto_rawDescData +} + +var file_core_services_synchronization_telem_telem_head_report_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_core_services_synchronization_telem_telem_head_report_proto_goTypes = []interface{}{ + (*HeadReportRequest)(nil), // 0: telem.HeadReportRequest +} +var file_core_services_synchronization_telem_telem_head_report_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_core_services_synchronization_telem_telem_head_report_proto_init() } +func file_core_services_synchronization_telem_telem_head_report_proto_init() { + if File_core_services_synchronization_telem_telem_head_report_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HeadReportRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_core_services_synchronization_telem_telem_head_report_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_core_services_synchronization_telem_telem_head_report_proto_goTypes, + DependencyIndexes: file_core_services_synchronization_telem_telem_head_report_proto_depIdxs, + MessageInfos: file_core_services_synchronization_telem_telem_head_report_proto_msgTypes, + }.Build() + File_core_services_synchronization_telem_telem_head_report_proto = out.File + file_core_services_synchronization_telem_telem_head_report_proto_rawDesc = nil + file_core_services_synchronization_telem_telem_head_report_proto_goTypes = nil + file_core_services_synchronization_telem_telem_head_report_proto_depIdxs = nil +} diff --git a/core/services/synchronization/telem/telem_head_report.proto b/core/services/synchronization/telem/telem_head_report.proto new file mode 100644 index 00000000000..e7d88e06ef2 --- /dev/null +++ b/core/services/synchronization/telem/telem_head_report.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +option go_package = "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem"; + +package telem; + +message HeadReportRequest { + string chain_id=1; + uint64 timestamp = 3; + uint64 block_number = 4; + string block_hash = 5; + bool finalized = 6; +} \ No newline at end of file From dba6b945e6c188b32842b6b5159bdbc403e1a783 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Fri, 21 Jun 2024 17:00:49 +0100 Subject: [PATCH 02/21] tests tests review fixes ci fixes ci fixes telemetry reporter test fix chain in proto fix chain in proto fix ci changeset fix config test review fix fix config test fix docs test fix config testscript fix config testscript fix test --- .changeset/proud-jokes-exercise.md | 5 + core/config/app_config.go | 1 + core/config/docs/core.toml | 4 + core/config/head_report_config.go | 5 + core/config/toml/types.go | 12 ++ core/internal/mocks/head_reporter.go | 66 ++++++++ core/services/chainlink/application.go | 2 +- core/services/chainlink/config_general.go | 6 + .../services/chainlink/config_general_test.go | 1 + core/services/chainlink/config_head_report.go | 13 ++ .../chainlink/config_head_report_test.go | 18 +++ core/services/chainlink/config_test.go | 7 +- .../chainlink/mocks/general_config.go | 20 +++ .../testdata/config-empty-effective.toml | 3 + .../chainlink/testdata/config-full.toml | 3 + .../config-multi-chain-effective.toml | 3 + core/services/headreporter/head_reporter.go | 119 ++++++++------ .../headreporter/head_reporter_test.go | 117 +++----------- .../headreporter/prometheus_reporter.go | 28 ++-- .../headreporter/prometheus_reporter_test.go | 96 +++++++++++ .../headreporter/telemetry_reporter.go | 61 ++++--- .../headreporter/telemetry_reporter_test.go | 145 +++++++++++++++++ .../telem/telem_head_report.pb.go | 149 ++++++++++++------ .../telem/telem_head_report.proto | 16 +- core/services/telemetry/common.go | 1 + .../mocks/monitoring_endpoint_generator.go | 49 ++++++ .../testdata/config-empty-effective.toml | 3 + core/web/resolver/testdata/config-full.toml | 3 + .../config-multi-chain-effective.toml | 3 + core/web/testdata/body/health.html | 6 +- core/web/testdata/body/health.json | 18 +-- core/web/testdata/body/health.txt | 2 +- docs/CONFIG.md | 13 ++ testdata/scripts/health/default.txtar | 20 +-- testdata/scripts/health/multi-chain.txtar | 20 +-- testdata/scripts/node/validate/default.txtar | 3 + .../disk-based-logging-disabled.txtar | 3 + .../validate/disk-based-logging-no-dir.txtar | 3 + .../node/validate/disk-based-logging.txtar | 3 + .../node/validate/invalid-ocr-p2p.txtar | 3 + testdata/scripts/node/validate/invalid.txtar | 3 + testdata/scripts/node/validate/valid.txtar | 3 + testdata/scripts/node/validate/warnings.txtar | 3 + 43 files changed, 798 insertions(+), 264 deletions(-) create mode 100644 .changeset/proud-jokes-exercise.md create mode 100644 core/config/head_report_config.go create mode 100644 core/internal/mocks/head_reporter.go create mode 100644 core/services/chainlink/config_head_report.go create mode 100644 core/services/chainlink/config_head_report_test.go create mode 100644 core/services/headreporter/prometheus_reporter_test.go create mode 100644 core/services/headreporter/telemetry_reporter_test.go create mode 100644 core/services/telemetry/mocks/monitoring_endpoint_generator.go diff --git a/.changeset/proud-jokes-exercise.md b/.changeset/proud-jokes-exercise.md new file mode 100644 index 00000000000..4e36d139de5 --- /dev/null +++ b/.changeset/proud-jokes-exercise.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#added Report new heads as a telemetry to OTI diff --git a/core/config/app_config.go b/core/config/app_config.go index 112e242636f..fe877d110ab 100644 --- a/core/config/app_config.go +++ b/core/config/app_config.go @@ -53,6 +53,7 @@ type AppConfig interface { Pyroscope() Pyroscope Sentry() Sentry TelemetryIngress() TelemetryIngress + HeadReport() HeadReport Threshold() Threshold WebServer() WebServer Tracing() Tracing diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index d0960779c6c..e45a7cd3841 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -651,3 +651,7 @@ TransmitQueueMaxSize = 10_000 # Default # when sending a message to the mercury server, before aborting and considering # the transmission to be failed. TransmitTimeout = "5s" # Default + +[HeadReport] +# TelemetryEnabled controls if it collects information about new blocks from blockchain +TelemetryEnabled = false # Default diff --git a/core/config/head_report_config.go b/core/config/head_report_config.go new file mode 100644 index 00000000000..9f4ae85eb6c --- /dev/null +++ b/core/config/head_report_config.go @@ -0,0 +1,5 @@ +package config + +type HeadReport interface { + TelemetryEnabled() bool +} diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 0c91ddd81a9..a503720ea9e 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -56,6 +56,7 @@ type Core struct { Insecure Insecure `toml:",omitempty"` Tracing Tracing `toml:",omitempty"` Mercury Mercury `toml:",omitempty"` + HeadReport HeadReport `toml:",omitempty"` Capabilities Capabilities `toml:",omitempty"` } @@ -76,6 +77,7 @@ func (c *Core) SetFrom(f *Core) { c.TelemetryIngress.setFrom(&f.TelemetryIngress) c.AuditLogger.SetFrom(&f.AuditLogger) c.Log.setFrom(&f.Log) + c.HeadReport.setFrom(&f.HeadReport) c.WebServer.setFrom(&f.WebServer) c.JobPipeline.setFrom(&f.JobPipeline) @@ -485,6 +487,16 @@ func (t *TelemetryIngress) setFrom(f *TelemetryIngress) { } } +type HeadReport struct { + TelemetryEnabled *bool +} + +func (t *HeadReport) setFrom(f *HeadReport) { + if v := f.TelemetryEnabled; v != nil { + t.TelemetryEnabled = v + } +} + type AuditLogger struct { Enabled *bool ForwardToUrl *commonconfig.URL diff --git a/core/internal/mocks/head_reporter.go b/core/internal/mocks/head_reporter.go new file mode 100644 index 00000000000..49e4e7f491d --- /dev/null +++ b/core/internal/mocks/head_reporter.go @@ -0,0 +1,66 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" +) + +// HeadReporter is an autogenerated mock type for the HeadReporter type +type HeadReporter struct { + mock.Mock +} + +// ReportNewHead provides a mock function with given fields: ctx, head +func (_m *HeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { + ret := _m.Called(ctx, head) + + if len(ret) == 0 { + panic("no return value specified for ReportNewHead") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok { + r0 = rf(ctx, head) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ReportPeriodic provides a mock function with given fields: ctx +func (_m *HeadReporter) ReportPeriodic(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ReportPeriodic") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewHeadReporter creates a new instance of HeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewHeadReporter(t interface { + mock.TestingT + Cleanup(func()) +}) *HeadReporter { + mock := &HeadReporter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 6649b4fc6c8..5118bb9ec68 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -323,7 +323,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { srvcs = append(srvcs, mailMon) srvcs = append(srvcs, relayerChainInterops.Services()...) - headReporter := headreporter.NewHeadReporter(opts.DS, legacyEVMChains, globalLogger) + headReporter := headreporter.NewHeadReporterService(cfg.HeadReport(), opts.DS, legacyEVMChains, globalLogger, telemetryManager) srvcs = append(srvcs, headReporter) // Initialize Local Users ORM and Authentication Provider specified in config diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index 5b6b839fb5e..abdd48d7592 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -483,6 +483,12 @@ func (g *generalConfig) RootDir() string { return h } +func (g *generalConfig) HeadReport() coreconfig.HeadReport { + return &headReport{ + h: g.c.HeadReport, + } +} + func (g *generalConfig) TelemetryIngress() coreconfig.TelemetryIngress { return &telemetryIngressConfig{ c: g.c.TelemetryIngress, diff --git a/core/services/chainlink/config_general_test.go b/core/services/chainlink/config_general_test.go index 29393ee0fdd..6247ebd91c8 100644 --- a/core/services/chainlink/config_general_test.go +++ b/core/services/chainlink/config_general_test.go @@ -30,6 +30,7 @@ func TestTOMLGeneralConfig_Defaults(t *testing.T) { assert.False(t, config.StarkNetEnabled()) assert.Equal(t, false, config.JobPipeline().ExternalInitiatorsEnabled()) assert.Equal(t, 15*time.Minute, config.WebServer().SessionTimeout().Duration()) + assert.Equal(t, false, config.HeadReport().TelemetryEnabled()) } func TestTOMLGeneralConfig_InsecureConfig(t *testing.T) { diff --git a/core/services/chainlink/config_head_report.go b/core/services/chainlink/config_head_report.go new file mode 100644 index 00000000000..e6e292938d9 --- /dev/null +++ b/core/services/chainlink/config_head_report.go @@ -0,0 +1,13 @@ +package chainlink + +import ( + "github.com/smartcontractkit/chainlink/v2/core/config/toml" +) + +type headReport struct { + h toml.HeadReport +} + +func (h headReport) TelemetryEnabled() bool { + return *h.h.TelemetryEnabled +} diff --git a/core/services/chainlink/config_head_report_test.go b/core/services/chainlink/config_head_report_test.go new file mode 100644 index 00000000000..1840c4f578b --- /dev/null +++ b/core/services/chainlink/config_head_report_test.go @@ -0,0 +1,18 @@ +package chainlink + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestHeadReportConfig(t *testing.T) { + opts := GeneralConfigOpts{ + ConfigStrings: []string{fullTOML}, + } + cfg, err := opts.New() + require.NoError(t, err) + + hr := cfg.HeadReport() + require.True(t, hr.TelemetryEnabled()) +} diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index f5a9d335928..bd75e92b23b 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -733,7 +733,9 @@ func TestConfig_Marshal(t *testing.T) { }, VerboseLogging: ptr(true), } - + full.HeadReport = toml.HeadReport{ + TelemetryEnabled: ptr(true), + } for _, tt := range []struct { name string config Config @@ -1204,6 +1206,9 @@ CertFile = '/path/to/cert.pem' [Mercury.Transmitter] TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' +`}, + {"HeadReport", Config{Core: toml.Core{HeadReport: full.HeadReport}}, `[HeadReport] +TelemetryEnabled = true `}, {"full", full, fullTOML}, {"multi-chain", multiChain, multiChainTOML}, diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index c42ed5c7014..ae2e73768b6 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -692,6 +692,26 @@ func (_c *GeneralConfig_FluxMonitor_Call) RunAndReturn(run func() config.FluxMon return _c } +// HeadReport provides a mock function with given fields: +func (_m *GeneralConfig) HeadReport() config.HeadReport { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for HeadReport") + } + + var r0 config.HeadReport + if rf, ok := ret.Get(0).(func() config.HeadReport); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(config.HeadReport) + } + } + + return r0 +} + // Insecure provides a mock function with given fields: func (_m *GeneralConfig) Insecure() config.Insecure { ret := _m.Called() diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index f1325d824ea..93a5e509ab1 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -237,6 +237,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index d752398f039..b2c342f33c7 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -247,6 +247,9 @@ CertFile = '/path/to/cert.pem' TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' +[HeadReport] +TelemetryEnabled = true + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 12427650f42..f97e31f5b7d 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -237,6 +237,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/services/headreporter/head_reporter.go b/core/services/headreporter/head_reporter.go index 2dbd7890a3b..c2dee2c015d 100644 --- a/core/services/headreporter/head_reporter.go +++ b/core/services/headreporter/head_reporter.go @@ -2,10 +2,13 @@ package headreporter import ( "context" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "sync" "time" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink/v2/core/config" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" @@ -14,14 +17,14 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" ) -//go:generate mockery --quiet --name PrometheusBackend --output ../../internal/mocks/ --case=underscore +//go:generate mockery --quiet --name HeadReporter --output ../../internal/mocks/ --case=underscore type ( - Reporter interface { - reportOnHead(ctx context.Context, head *evmtypes.Head) - reportPeriodic(ctx context.Context) + HeadReporter interface { + ReportNewHead(ctx context.Context, head *evmtypes.Head) error + ReportPeriodic(ctx context.Context) error } - headReporter struct { + HeadReporterService struct { services.StateMachine ds sqlutil.DataSource chains legacyevm.LegacyChainContainer @@ -30,76 +33,98 @@ type ( chStop services.StopChan wgDone sync.WaitGroup reportPeriod time.Duration - reporters []Reporter + reporters []HeadReporter } ) -var ( - name = "HeadReporter" -) +func NewHeadReporterService(config config.HeadReport, ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, opts ...interface{}) *HeadReporterService { + reporters := make([]HeadReporter, 1, 2) + reporters[0] = NewPrometheusReporter(ds, chainContainer, lggr, opts) + if config.TelemetryEnabled() { + reporters = append(reporters, NewTelemetryReporter(chainContainer, lggr, monitoringEndpointGen)) + } + return NewHeadReporterServiceWithReporters(ds, chainContainer, lggr, reporters, opts) +} -func NewHeadReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *headReporter { +func NewHeadReporterServiceWithReporters(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, reporters []HeadReporter, opts ...interface{}) *HeadReporterService { + reportPeriod := 30 * time.Second + for _, opt := range opts { + switch v := opt.(type) { + case time.Duration: + reportPeriod = v + default: + lggr.Debugf("Unknown opt type '%T' passed to HeadReporterService", v) + } + } chStop := make(chan struct{}) - return &headReporter{ - ds: ds, - chains: chainContainer, - lggr: lggr.Named(name), - newHeads: mailbox.NewSingle[*evmtypes.Head](), - chStop: chStop, - reporters: []Reporter{ - NewPrometheusReporter(ds, chainContainer, lggr, opts), - NewTelemetryReporter(chainContainer, lggr), - }, + return &HeadReporterService{ + ds: ds, + chains: chainContainer, + lggr: lggr.Named("HeadReporterService"), + newHeads: mailbox.NewSingle[*evmtypes.Head](), + chStop: chStop, + wgDone: sync.WaitGroup{}, + reportPeriod: reportPeriod, + reporters: reporters, } } -func (rr *headReporter) Start(context.Context) error { - return rr.StartOnce(name, func() error { - rr.wgDone.Add(1) - go rr.eventLoop() +func (hrd *HeadReporterService) Start(context.Context) error { + return hrd.StartOnce(hrd.Name(), func() error { + hrd.wgDone.Add(1) + go hrd.eventLoop() return nil }) } -func (rr *headReporter) Close() error { - return rr.StopOnce(name, func() error { - close(rr.chStop) - rr.wgDone.Wait() +func (hrd *HeadReporterService) Close() error { + return hrd.StopOnce(hrd.Name(), func() error { + close(hrd.chStop) + hrd.wgDone.Wait() return nil }) } -func (rr *headReporter) Name() string { - return rr.lggr.Name() + +func (hrd *HeadReporterService) Name() string { + return hrd.lggr.Name() } -func (rr *headReporter) HealthReport() map[string]error { - return map[string]error{rr.Name(): rr.Healthy()} +func (hrd *HeadReporterService) HealthReport() map[string]error { + return map[string]error{hrd.Name(): hrd.Healthy()} } -func (rr *headReporter) OnNewLongestChain(ctx context.Context, head *evmtypes.Head) { - rr.newHeads.Deliver(head) +func (hrd *HeadReporterService) OnNewLongestChain(ctx context.Context, head *evmtypes.Head) { + hrd.newHeads.Deliver(head) } -func (rr *headReporter) eventLoop() { - rr.lggr.Debug("Starting event loop") - defer rr.wgDone.Done() - ctx, cancel := rr.chStop.NewCtx() +func (hrd *HeadReporterService) eventLoop() { + hrd.lggr.Debug("Starting event loop") + defer hrd.wgDone.Done() + ctx, cancel := hrd.chStop.NewCtx() defer cancel() + after := time.After(hrd.reportPeriod) for { select { - case <-rr.newHeads.Notify(): - head, exists := rr.newHeads.Retrieve() + case <-hrd.newHeads.Notify(): + head, exists := hrd.newHeads.Retrieve() if !exists { continue } - for _, reporter := range rr.reporters { - reporter.reportOnHead(ctx, head) + for _, reporter := range hrd.reporters { + err := reporter.ReportNewHead(ctx, head) + if err != nil && ctx.Err() == nil { + hrd.lggr.Errorw("Error reporting new head", "err", err) + } } - case <-time.After(rr.reportPeriod): - for _, reporter := range rr.reporters { - reporter.reportPeriodic(ctx) + case <-after: + for _, reporter := range hrd.reporters { + err := reporter.ReportPeriodic(ctx) + if err != nil && ctx.Err() == nil { + hrd.lggr.Errorw("Error in periodic report", "err", err) + } } - case <-rr.chStop: + after = time.After(hrd.reportPeriod) + case <-hrd.chStop: return } } diff --git a/core/services/headreporter/head_reporter_test.go b/core/services/headreporter/head_reporter_test.go index 2383f60be50..6effef1ff3c 100644 --- a/core/services/headreporter/head_reporter_test.go +++ b/core/services/headreporter/head_reporter_test.go @@ -1,29 +1,29 @@ package headreporter_test import ( - "math/big" "sync/atomic" "testing" "time" - "github.com/jmoiron/sqlx" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" - "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/jmoiron/sqlx" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" @@ -70,94 +70,25 @@ func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainCon return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) } -func Test_PromReporter_OnNewLongestChain(t *testing.T) { - t.Run("with nothing in the database", func(t *testing.T) { +func Test_HeadReporterService(t *testing.T) { + t.Run("report everything", func(t *testing.T) { db := pgtest.NewSqlxDB(t) - backend := mocks.NewPrometheusBackend(t) - reporter := headreporter.NewHeadReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) - - var subscribeCalls atomic.Int32 - - backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() - backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() - backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - backend.On("SetPipelineTaskRunsQueued", 0).Return() - backend.On("SetPipelineRunsQueued", 0). - Run(func(args mock.Arguments) { - subscribeCalls.Add(1) - }). - Return() - - servicetest.Run(t, reporter) + headReporter := mocks.NewHeadReporter(t) + service := headreporter.NewHeadReporterServiceWithReporters(db, newLegacyChainContainer(t, db), logger.TestLogger(t), []headreporter.HeadReporter{headReporter}, time.Second) + err := service.Start(testutils.Context(t)) + require.NoError(t, err) + var reportCalls atomic.Int32 head := newHead() - reporter.OnNewLongestChain(testutils.Context(t), &head) - - require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond) - }) - - t.Run("with unconfirmed evm.txes", func(t *testing.T) { - db := pgtest.NewSqlxDB(t) - txStore := cltest.NewTestTxStore(t, db) - ethKeyStore := cltest.NewKeyStore(t, db).Eth() - _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) - - var subscribeCalls atomic.Int32 - - backend := mocks.NewPrometheusBackend(t) - backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(3)).Return() - backend.On("SetMaxUnconfirmedAge", big.NewInt(0), mock.MatchedBy(func(s float64) bool { - return s > 0 - })).Return() - backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(35)).Return() - backend.On("SetPipelineTaskRunsQueued", 0).Return() - backend.On("SetPipelineRunsQueued", 0). - Run(func(args mock.Arguments) { - subscribeCalls.Add(1) - }). - Return() - reporter := headreporter.NewHeadReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) - servicetest.Run(t, reporter) - - etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) - cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress) - cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) - require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7)) - - head := newHead() - reporter.OnNewLongestChain(testutils.Context(t), &head) - - require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond) - }) - - t.Run("with unfinished pipeline task runs", func(t *testing.T) { - db := pgtest.NewSqlxDB(t) - pgtest.MustExec(t, db, `SET CONSTRAINTS pipeline_task_runs_pipeline_run_id_fkey DEFERRED`) - - backend := mocks.NewPrometheusBackend(t) - reporter := headreporter.NewHeadReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) - - cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) - cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) - cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 2) - - var subscribeCalls atomic.Int32 - - backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() - backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() - backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - backend.On("SetPipelineTaskRunsQueued", 3).Return() - backend.On("SetPipelineRunsQueued", 2). - Run(func(args mock.Arguments) { - subscribeCalls.Add(1) - }). - Return() - servicetest.Run(t, reporter) - - head := newHead() - reporter.OnNewLongestChain(testutils.Context(t), &head) - - require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond) + headReporter.On("ReportNewHead", mock.Anything, &head).Run(func(args mock.Arguments) { + reportCalls.Add(1) + }).Return(nil) + headReporter.On("ReportPeriodic", mock.Anything).Run(func(args mock.Arguments) { + reportCalls.Add(1) + }).Return(nil) + service.OnNewLongestChain(testutils.Context(t), &head) + + require.Eventually(t, func() bool { return reportCalls.Load() == 2 }, 5*time.Second, 100*time.Millisecond) }) } diff --git a/core/services/headreporter/prometheus_reporter.go b/core/services/headreporter/prometheus_reporter.go index 7ad4965cfc9..5d8cf42bc49 100644 --- a/core/services/headreporter/prometheus_reporter.go +++ b/core/services/headreporter/prometheus_reporter.go @@ -3,25 +3,26 @@ package headreporter import ( "context" "fmt" + "math/big" + "time" + "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "go.uber.org/multierr" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" - "go.uber.org/multierr" - "math/big" - "time" ) type ( prometheusReporter struct { ds sqlutil.DataSource chains legacyevm.LegacyChainContainer - lggr logger.Logger backend PrometheusBackend } @@ -59,18 +60,19 @@ var ( }) ) -func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *prometheusReporter { +func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) HeadReporter { var backend PrometheusBackend = defaultBackend{} for _, opt := range opts { switch v := opt.(type) { case PrometheusBackend: backend = v + default: + lggr.Debugf("Unknown opt type '%T' passed to PrometheusReporter", v) } } return &prometheusReporter{ ds: ds, chains: chainContainer, - lggr: lggr.Named(name), backend: backend, } } @@ -83,17 +85,13 @@ func (pr *prometheusReporter) getTxm(evmChainID *big.Int) (txmgr.TxManager, erro return chain.TxManager(), nil } -func (pr *prometheusReporter) reportOnHead(ctx context.Context, head *evmtypes.Head) { +func (pr *prometheusReporter) ReportNewHead(ctx context.Context, head *evmtypes.Head) error { evmChainID := head.EVMChainID.ToInt() - err := multierr.Combine( + return multierr.Combine( errors.Wrap(pr.reportPendingEthTxes(ctx, evmChainID), "reportPendingEthTxes failed"), errors.Wrap(pr.reportMaxUnconfirmedAge(ctx, evmChainID), "reportMaxUnconfirmedAge failed"), errors.Wrap(pr.reportMaxUnconfirmedBlocks(ctx, head), "reportMaxUnconfirmedBlocks failed"), ) - - if err != nil && ctx.Err() == nil { - pr.lggr.Errorw("Error reporting prometheus metrics", "err", err) - } } func (pr *prometheusReporter) reportPendingEthTxes(ctx context.Context, evmChainID *big.Int) (err error) { @@ -148,10 +146,8 @@ func (pr *prometheusReporter) reportMaxUnconfirmedBlocks(ctx context.Context, he return nil } -func (pr *prometheusReporter) reportPeriodic(ctx context.Context) { - if err := errors.Wrap(pr.reportPipelineRunStats(ctx), "reportPipelineRunStats failed"); err != nil { - pr.lggr.Errorw("Error reporting prometheus metrics", "err", err) - } +func (pr *prometheusReporter) ReportPeriodic(ctx context.Context) error { + return errors.Wrap(pr.reportPipelineRunStats(ctx), "reportPipelineRunStats failed") } func (pr *prometheusReporter) reportPipelineRunStats(ctx context.Context) (err error) { diff --git a/core/services/headreporter/prometheus_reporter_test.go b/core/services/headreporter/prometheus_reporter_test.go new file mode 100644 index 00000000000..131805cd7a5 --- /dev/null +++ b/core/services/headreporter/prometheus_reporter_test.go @@ -0,0 +1,96 @@ +package headreporter_test + +import ( + "math/big" + "testing" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" +) + +func Test_PrometheusReporter(t *testing.T) { + t.Run("with nothing in the database", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + + backend := mocks.NewPrometheusBackend(t) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) + + backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() + backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() + backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() + + head := newHead() + err := reporter.ReportNewHead(testutils.Context(t), &head) + require.NoError(t, err) + + backend.On("SetPipelineTaskRunsQueued", 0).Return() + backend.On("SetPipelineRunsQueued", 0).Return() + err = reporter.ReportPeriodic(testutils.Context(t)) + require.NoError(t, err) + }) + + t.Run("with unconfirmed evm.txes", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + txStore := cltest.NewTestTxStore(t, db) + ethKeyStore := cltest.NewKeyStore(t, db).Eth() + _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) + + etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) + cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress) + cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) + require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7)) + + backend := mocks.NewPrometheusBackend(t) + backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(3)).Return() + backend.On("SetMaxUnconfirmedAge", big.NewInt(0), mock.MatchedBy(func(s float64) bool { + return s > 0 + })).Return() + backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(35)).Return() + + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) + + head := newHead() + err := reporter.ReportNewHead(testutils.Context(t), &head) + require.NoError(t, err) + + backend.On("SetPipelineTaskRunsQueued", 0).Return() + backend.On("SetPipelineRunsQueued", 0).Return() + + err = reporter.ReportPeriodic(testutils.Context(t)) + require.NoError(t, err) + }) + + t.Run("with unfinished pipeline task runs", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + pgtest.MustExec(t, db, `SET CONSTRAINTS pipeline_task_runs_pipeline_run_id_fkey DEFERRED`) + + cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) + cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) + cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 2) + + backend := mocks.NewPrometheusBackend(t) + backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() + backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() + backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() + + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) + + head := newHead() + err := reporter.ReportNewHead(testutils.Context(t), &head) + require.NoError(t, err) + + backend.On("SetPipelineTaskRunsQueued", 3).Return() + backend.On("SetPipelineRunsQueued", 2).Return() + + err = reporter.ReportPeriodic(testutils.Context(t)) + require.NoError(t, err) + }) +} diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go index bceaa18fd76..241296a7e46 100644 --- a/core/services/headreporter/telemetry_reporter.go +++ b/core/services/headreporter/telemetry_reporter.go @@ -2,52 +2,67 @@ package headreporter import ( "context" + + "github.com/pkg/errors" + + "github.com/smartcontractkit/libocr/commontypes" + "google.golang.org/protobuf/proto" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/smartcontractkit/libocr/commontypes" - "google.golang.org/protobuf/proto" - "math/big" ) type ( telemetryReporter struct { - logger logger.Logger - endpoints map[*big.Int]commontypes.MonitoringEndpoint + endpoints map[uint64]commontypes.MonitoringEndpoint } ) -func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) *telemetryReporter { - endpoints := make(map[*big.Int]commontypes.MonitoringEndpoint) +func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { + endpoints := make(map[uint64]commontypes.MonitoringEndpoint) for _, chain := range chainContainer.Slice() { - endpoints[chain.ID()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chain.ID().String(), "", synchronization.HeadReport) - } - return &telemetryReporter{ - logger: lggr, - endpoints: endpoints, + endpoints[chain.ID().Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chain.ID().String(), "", synchronization.HeadReport) } + return &telemetryReporter{endpoints: endpoints} } -func (t *telemetryReporter) reportOnHead(ctx context.Context, head *evmtypes.Head) { - monitoringEndpoint := t.endpoints[head.EVMChainID.ToInt()] +func (t *telemetryReporter) ReportNewHead(ctx context.Context, head *evmtypes.Head) error { + monitoringEndpoint := t.endpoints[head.EVMChainID.ToInt().Uint64()] + if monitoringEndpoint == nil { + return errors.Errorf("No monitoring endpoint provided chain_id=%d", head.EVMChainID.Int64()) + } + var finalized *telem.Block + latestFinalizedHead := head.LatestFinalizedHead() + if latestFinalizedHead != nil { + finalized = &telem.Block{ + Timestamp: uint64(latestFinalizedHead.GetTimestamp().UTC().Unix()), + Number: uint64(latestFinalizedHead.BlockNumber()), + Hash: latestFinalizedHead.BlockHash().Hex(), + } + } request := &telem.HeadReportRequest{ - ChainId: head.EVMChainID.String(), - Timestamp: uint64(head.Timestamp.UTC().Unix()), - BlockNumber: uint64(head.Number), - BlockHash: head.Hash.Hex(), - Finalized: head.IsFinalized, + Latest: &telem.Block{ + Timestamp: uint64(head.Timestamp.UTC().Unix()), + Number: uint64(head.Number), + Hash: head.Hash.Hex(), + }, + Finalized: finalized, } bytes, err := proto.Marshal(request) if err != nil { - t.logger.Warnw("telem.HeadReportRequest marshal error", "err", err) - return + return errors.WithMessage(err, "telem.HeadReportRequest marshal error") } monitoringEndpoint.SendLog(bytes) + if finalized == nil { + return errors.Errorf("No finalized block was found for chain_id=%d", head.EVMChainID.Int64()) + } + return nil } -func (t *telemetryReporter) reportPeriodic(ctx context.Context) { - //do nothing +func (t *telemetryReporter) ReportPeriodic(ctx context.Context) error { + return nil } diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go new file mode 100644 index 00000000000..bfb24d8ed01 --- /dev/null +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -0,0 +1,145 @@ +package headreporter_test + +import ( + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "google.golang.org/protobuf/proto" + + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" + mocks2 "github.com/smartcontractkit/chainlink/v2/core/services/telemetry/mocks" +) + +type IngressAgent struct { + mock.Mock +} + +func (t *IngressAgent) SendLog(telemetry []byte) { + _ = t.Called(telemetry) +} + +func NewIngressAgent(t interface { + mock.TestingT + Cleanup(func()) +}) *IngressAgent { + m := &IngressAgent{} + m.Mock.Test(t) + + t.Cleanup(func() { m.AssertExpectations(t) }) + + return m +} + +func Test_TelemetryReporter_NewHead(t *testing.T) { + chain := mocks.NewChain(t) + chain.On("ID").Return(big.NewInt(100)) + + chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) + + ingressAgent := NewIngressAgent(t) + + monitoringEndpointGen := mocks2.NewMonitoringEndpointGenerator(t) + monitoringEndpointGen. + On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). + Return(ingressAgent) + reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + + head := evmtypes.Head{ + Number: 42, + EVMChainID: ubig.NewI(100), + Hash: common.HexToHash("0x1010"), + Timestamp: time.UnixMilli(1000), + IsFinalized: false, + Parent: &evmtypes.Head{ + Number: 41, + Hash: common.HexToHash("0x1009"), + Timestamp: time.UnixMilli(999), + IsFinalized: true, + }, + } + requestBytes, err := proto.Marshal(&telem.HeadReportRequest{ + Latest: &telem.Block{ + Timestamp: uint64(head.Timestamp.UTC().Unix()), + Number: 42, + Hash: head.Hash.Hex(), + }, + Finalized: &telem.Block{ + Timestamp: uint64(head.Parent.Timestamp.UTC().Unix()), + Number: 41, + Hash: head.Parent.Hash.Hex(), + }, + }) + assert.NoError(t, err) + + ingressAgent.On("SendLog", requestBytes).Return() + + err = reporter.ReportNewHead(testutils.Context(t), &head) + assert.NoError(t, err) +} + +func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { + chain := mocks.NewChain(t) + chain.On("ID").Return(big.NewInt(100)) + + chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) + + ingressAgent := NewIngressAgent(t) + + monitoringEndpointGen := mocks2.NewMonitoringEndpointGenerator(t) + monitoringEndpointGen. + On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). + Return(ingressAgent) + reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + + head := evmtypes.Head{ + Number: 42, + EVMChainID: ubig.NewI(100), + Hash: common.HexToHash("0x1010"), + Timestamp: time.UnixMilli(1000), + IsFinalized: false, + } + requestBytes, err := proto.Marshal(&telem.HeadReportRequest{ + Latest: &telem.Block{ + Timestamp: uint64(head.Timestamp.UTC().Unix()), + Number: 42, + Hash: head.Hash.Hex(), + }, + }) + assert.NoError(t, err) + + ingressAgent.On("SendLog", requestBytes).Return() + + err = reporter.ReportNewHead(testutils.Context(t), &head) + assert.Errorf(t, err, "No finalized block was found for chain_id=100") +} + +func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { + chain := mocks.NewChain(t) + chain.On("ID").Return(big.NewInt(100)) + + chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) + + monitoringEndpointGen := mocks2.NewMonitoringEndpointGenerator(t) + monitoringEndpointGen. + On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). + Return(nil) + + reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + + head := evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(100)} + + err := reporter.ReportNewHead(testutils.Context(t), &head) + assert.Errorf(t, err, "No monitoring endpoint provided chain_id=100") +} diff --git a/core/services/synchronization/telem/telem_head_report.pb.go b/core/services/synchronization/telem/telem_head_report.pb.go index 24d4ddd7ae8..18e4532472b 100644 --- a/core/services/synchronization/telem/telem_head_report.pb.go +++ b/core/services/synchronization/telem/telem_head_report.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.33.0 -// protoc v5.27.1 +// protoc v4.25.1 // source: core/services/synchronization/telem/telem_head_report.proto package telem @@ -25,12 +25,9 @@ type HeadReportRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - Node string `protobuf:"bytes,2,opt,name=node,proto3" json:"node,omitempty"` - Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - BlockNumber uint64 `protobuf:"varint,4,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` - BlockHash string `protobuf:"bytes,5,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` - Finalized bool `protobuf:"varint,6,opt,name=finalized,proto3" json:"finalized,omitempty"` + Chain string `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` + Latest *Block `protobuf:"bytes,2,opt,name=latest,proto3" json:"latest,omitempty"` + Finalized *Block `protobuf:"bytes,3,opt,name=finalized,proto3,oneof" json:"finalized,omitempty"` } func (x *HeadReportRequest) Reset() { @@ -65,46 +62,88 @@ func (*HeadReportRequest) Descriptor() ([]byte, []int) { return file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZIP(), []int{0} } -func (x *HeadReportRequest) GetChainId() string { +func (x *HeadReportRequest) GetChain() string { if x != nil { - return x.ChainId + return x.Chain } return "" } -func (x *HeadReportRequest) GetNode() string { +func (x *HeadReportRequest) GetLatest() *Block { if x != nil { - return x.Node + return x.Latest } - return "" + return nil } -func (x *HeadReportRequest) GetTimestamp() uint64 { +func (x *HeadReportRequest) GetFinalized() *Block { if x != nil { - return x.Timestamp + return x.Finalized } - return 0 + return nil +} + +type Block struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Number uint64 `protobuf:"varint,2,opt,name=number,proto3" json:"number,omitempty"` + Hash string `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"` +} + +func (x *Block) Reset() { + *x = Block{} + if protoimpl.UnsafeEnabled { + mi := &file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Block) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *HeadReportRequest) GetBlockNumber() uint64 { +func (*Block) ProtoMessage() {} + +func (x *Block) ProtoReflect() protoreflect.Message { + mi := &file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Block.ProtoReflect.Descriptor instead. +func (*Block) Descriptor() ([]byte, []int) { + return file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZIP(), []int{1} +} + +func (x *Block) GetTimestamp() uint64 { if x != nil { - return x.BlockNumber + return x.Timestamp } return 0 } -func (x *HeadReportRequest) GetBlockHash() string { +func (x *Block) GetNumber() uint64 { if x != nil { - return x.BlockHash + return x.Number } - return "" + return 0 } -func (x *HeadReportRequest) GetFinalized() bool { +func (x *Block) GetHash() string { if x != nil { - return x.Finalized + return x.Hash } - return false + return "" } var File_core_services_synchronization_telem_telem_head_report_proto protoreflect.FileDescriptor @@ -114,20 +153,26 @@ var file_core_services_synchronization_telem_telem_head_report_proto_rawDesc = [ 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x22, 0xc0, 0x01, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x66, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x3b, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6c, 0x65, 0x6d, 0x22, 0x8e, 0x01, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x12, 0x24, 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x06, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x51, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, + 0x6b, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -142,16 +187,19 @@ func file_core_services_synchronization_telem_telem_head_report_proto_rawDescGZI return file_core_services_synchronization_telem_telem_head_report_proto_rawDescData } -var file_core_services_synchronization_telem_telem_head_report_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_core_services_synchronization_telem_telem_head_report_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_core_services_synchronization_telem_telem_head_report_proto_goTypes = []interface{}{ (*HeadReportRequest)(nil), // 0: telem.HeadReportRequest + (*Block)(nil), // 1: telem.Block } var file_core_services_synchronization_telem_telem_head_report_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 1, // 0: telem.HeadReportRequest.latest:type_name -> telem.Block + 1, // 1: telem.HeadReportRequest.finalized:type_name -> telem.Block + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_core_services_synchronization_telem_telem_head_report_proto_init() } @@ -172,14 +220,27 @@ func file_core_services_synchronization_telem_telem_head_report_proto_init() { return nil } } + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Block); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } + file_core_services_synchronization_telem_telem_head_report_proto_msgTypes[0].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_core_services_synchronization_telem_telem_head_report_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/core/services/synchronization/telem/telem_head_report.proto b/core/services/synchronization/telem/telem_head_report.proto index e7d88e06ef2..e5a5edcd4b1 100644 --- a/core/services/synchronization/telem/telem_head_report.proto +++ b/core/services/synchronization/telem/telem_head_report.proto @@ -5,9 +5,13 @@ option go_package = "github.com/smartcontractkit/chainlink/v2/core/services/sync package telem; message HeadReportRequest { - string chain_id=1; - uint64 timestamp = 3; - uint64 block_number = 4; - string block_hash = 5; - bool finalized = 6; -} \ No newline at end of file + string chain = 1; + Block latest = 2; + optional Block finalized = 3; +} + +message Block { + uint64 timestamp = 1; + uint64 number = 2; + string hash = 3; +} diff --git a/core/services/telemetry/common.go b/core/services/telemetry/common.go index 37a92f16c6d..1ccd9674589 100644 --- a/core/services/telemetry/common.go +++ b/core/services/telemetry/common.go @@ -6,6 +6,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" ) +//go:generate mockery --quiet --name MonitoringEndpointGenerator --output ./mocks --case=underscore type MonitoringEndpointGenerator interface { GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) ocrtypes.MonitoringEndpoint } diff --git a/core/services/telemetry/mocks/monitoring_endpoint_generator.go b/core/services/telemetry/mocks/monitoring_endpoint_generator.go new file mode 100644 index 00000000000..717654f404f --- /dev/null +++ b/core/services/telemetry/mocks/monitoring_endpoint_generator.go @@ -0,0 +1,49 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + commontypes "github.com/smartcontractkit/libocr/commontypes" + mock "github.com/stretchr/testify/mock" + + synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" +) + +// MonitoringEndpointGenerator is an autogenerated mock type for the MonitoringEndpointGenerator type +type MonitoringEndpointGenerator struct { + mock.Mock +} + +// GenMonitoringEndpoint provides a mock function with given fields: network, chainID, contractID, telemType +func (_m *MonitoringEndpointGenerator) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { + ret := _m.Called(network, chainID, contractID, telemType) + + if len(ret) == 0 { + panic("no return value specified for GenMonitoringEndpoint") + } + + var r0 commontypes.MonitoringEndpoint + if rf, ok := ret.Get(0).(func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint); ok { + r0 = rf(network, chainID, contractID, telemType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(commontypes.MonitoringEndpoint) + } + } + + return r0 +} + +// NewMonitoringEndpointGenerator creates a new instance of MonitoringEndpointGenerator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMonitoringEndpointGenerator(t interface { + mock.TestingT + Cleanup(func()) +}) *MonitoringEndpointGenerator { + mock := &MonitoringEndpointGenerator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index f1325d824ea..93a5e509ab1 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -237,6 +237,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 9421e6198ee..ab6d0ab8447 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -247,6 +247,9 @@ CertFile = '' TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' +[HeadReport] +TelemetryEnabled = true + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 1c4093cbfca..5bf08c78346 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -237,6 +237,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/web/testdata/body/health.html b/core/web/testdata/body/health.html index 90d301bc8b8..1b93dfec43c 100644 --- a/core/web/testdata/body/health.html +++ b/core/web/testdata/body/health.html @@ -72,6 +72,9 @@ +
+ HeadReporterService +
JobSpawner
@@ -99,9 +102,6 @@ BridgeCache -
- PromReporter -
TelemetryManager
diff --git a/core/web/testdata/body/health.json b/core/web/testdata/body/health.json index 839428a5103..7f5f6bc2f95 100644 --- a/core/web/testdata/body/health.json +++ b/core/web/testdata/body/health.json @@ -108,6 +108,15 @@ "output": "" } }, + { + "type": "checks", + "id": "HeadReporterService", + "attributes": { + "name": "HeadReporterService", + "status": "passing", + "output": "" + } + }, { "type": "checks", "id": "JobSpawner", @@ -171,15 +180,6 @@ "output": "" } }, - { - "type": "checks", - "id": "PromReporter", - "attributes": { - "name": "PromReporter", - "status": "passing", - "output": "" - } - }, { "type": "checks", "id": "TelemetryManager", diff --git a/core/web/testdata/body/health.txt b/core/web/testdata/body/health.txt index 3709b4e15f0..876bc631a40 100644 --- a/core/web/testdata/body/health.txt +++ b/core/web/testdata/body/health.txt @@ -11,6 +11,7 @@ ok EVM.0.Txm.Broadcaster ok EVM.0.Txm.Confirmer ok EVM.0.Txm.Finalizer ok EVM.0.Txm.WrappedEvmEstimator +ok HeadReporterService ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool @@ -18,5 +19,4 @@ ok Mercury.WSRPCPool.CacheSet ok PipelineORM ok PipelineRunner ok PipelineRunner.BridgeCache -ok PromReporter ok TelemetryManager diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 74afcec7400..c2270599d00 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1768,6 +1768,19 @@ TransmitTimeout controls how long the transmitter will wait for a response when sending a message to the mercury server, before aborting and considering the transmission to be failed. +## HeadReport +```toml +[HeadReport] +TelemetryEnabled = false # Default +``` + + +### TelemetryEnabled +```toml +TelemetryEnabled = false # Default +``` +TelemetryEnabled controls if it collects information about new blocks from blockchain + ## EVM EVM defaults depend on ChainID: diff --git a/testdata/scripts/health/default.txtar b/testdata/scripts/health/default.txtar index 1dbf6b8eb96..55ce9aaa2f0 100644 --- a/testdata/scripts/health/default.txtar +++ b/testdata/scripts/health/default.txtar @@ -31,6 +31,7 @@ fj293fbBnlQ!f9vNs HTTPPort = $PORT -- out.txt -- +ok HeadReporterService ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool @@ -38,12 +39,20 @@ ok Mercury.WSRPCPool.CacheSet ok PipelineORM ok PipelineRunner ok PipelineRunner.BridgeCache -ok PromReporter ok TelemetryManager -- out.json -- { "data": [ + { + "type": "checks", + "id": "HeadReporterService", + "attributes": { + "name": "HeadReporterService", + "status": "passing", + "output": "" + } + }, { "type": "checks", "id": "JobSpawner", @@ -107,15 +116,6 @@ ok TelemetryManager "output": "" } }, - { - "type": "checks", - "id": "PromReporter", - "attributes": { - "name": "PromReporter", - "status": "passing", - "output": "" - } - }, { "type": "checks", "id": "TelemetryManager", diff --git a/testdata/scripts/health/multi-chain.txtar b/testdata/scripts/health/multi-chain.txtar index 76937329cb8..b9410b3898e 100644 --- a/testdata/scripts/health/multi-chain.txtar +++ b/testdata/scripts/health/multi-chain.txtar @@ -84,6 +84,7 @@ ok EVM.1.Txm.Broadcaster ok EVM.1.Txm.Confirmer ok EVM.1.Txm.Finalizer ok EVM.1.Txm.WrappedEvmEstimator +ok HeadReporterService ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool @@ -91,7 +92,6 @@ ok Mercury.WSRPCPool.CacheSet ok PipelineORM ok PipelineRunner ok PipelineRunner.BridgeCache -ok PromReporter ok Solana.Bar ok StarkNet.Baz ok TelemetryManager @@ -238,6 +238,15 @@ ok TelemetryManager "output": "" } }, + { + "type": "checks", + "id": "HeadReporterService", + "attributes": { + "name": "HeadReporterService", + "status": "passing", + "output": "" + } + }, { "type": "checks", "id": "JobSpawner", @@ -301,15 +310,6 @@ ok TelemetryManager "output": "" } }, - { - "type": "checks", - "id": "PromReporter", - "attributes": { - "name": "PromReporter", - "status": "passing", - "output": "" - } - }, { "type": "checks", "id": "Solana.Bar", diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index ff8b4889c49..10897c897c7 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -249,6 +249,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index f4dd43cb900..c25e5662daf 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -293,6 +293,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 75a6ae36418..9b7410df901 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -293,6 +293,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 97bae5a84b6..302700174b5 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -293,6 +293,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 0cdf001eccd..6fa9ca932a8 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -278,6 +278,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index ab6860ec790..99410d91078 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -283,6 +283,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index 603fdaada66..d11377ec74a 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -290,6 +290,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index dea40ec8da0..9d27734d058 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -272,6 +272,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 From d9d086bdb58e8f34f7bdb628cd40c5493b579082 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Thu, 25 Jul 2024 17:02:31 +0200 Subject: [PATCH 03/21] move to relayer move to relayer move service to evm --- core/cmd/shell.go | 10 ++++- core/cmd/shell_local_test.go | 2 +- core/internal/cltest/cltest.go | 9 +++- core/internal/cltest/mocks.go | 2 + core/services/chainlink/application.go | 14 +++--- .../chainlink/relayer_chain_interoperators.go | 8 +++- .../relayer_chain_interoperators_test.go | 13 ++++-- .../evm}/headreporter/head_reporter.go | 43 ++++++++++++------- .../evm}/headreporter/head_reporter_test.go | 3 +- .../evm}/headreporter/prometheus_reporter.go | 0 .../headreporter/prometheus_reporter_test.go | 3 +- .../evm}/headreporter/telemetry_reporter.go | 0 .../headreporter/telemetry_reporter_test.go | 3 +- 13 files changed, 73 insertions(+), 37 deletions(-) rename core/services/{ => relay/evm}/headreporter/head_reporter.go (78%) rename core/services/{ => relay/evm}/headreporter/head_reporter_test.go (97%) rename core/services/{ => relay/evm}/headreporter/prometheus_reporter.go (100%) rename core/services/{ => relay/evm}/headreporter/prometheus_reporter_test.go (97%) rename core/services/{ => relay/evm}/headreporter/telemetry_reporter.go (100%) rename core/services/{ => relay/evm}/headreporter/telemetry_reporter_test.go (98%) diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 3d055bb03a9..e146115ba04 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -19,6 +19,8 @@ import ( "sync" "time" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + "github.com/Depado/ginprom" "github.com/Masterminds/semver/v3" "github.com/getsentry/sentry-go" @@ -182,9 +184,14 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G ChainOpts: legacyevm.ChainOpts{AppConfig: cfg, MailMon: mailMon, DS: ds}, MercuryTransmitter: cfg.Mercury().Transmitter(), } + + telemetryManager := telemetry.NewManager(cfg.TelemetryIngress(), keyStore.CSA(), appLggr) // evm always enabled for backward compatibility // TODO BCF-2510 this needs to change in order to clear the path for EVM extraction - initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitDummy(ctx, relayerFactory), chainlink.InitEVM(ctx, relayerFactory, evmFactoryCfg)} + initOps := []chainlink.CoreRelayerChainInitFunc{ + chainlink.InitDummy(ctx, relayerFactory), + chainlink.InitEVM(ctx, relayerFactory, evmFactoryCfg, telemetryManager), + } if cfg.CosmosEnabled() { cosmosCfg := chainlink.CosmosFactoryConfig{ @@ -240,6 +247,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G GRPCOpts: grpcOpts, MercuryPool: mercuryPool, CapabilitiesRegistry: capabilitiesRegistry, + TelemetryManager: telemetryManager, }) } diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 8ed48dcaa20..6ec561f1bed 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -52,7 +52,7 @@ func genTestEVMRelayers(t *testing.T, opts legacyevm.ChainRelayExtenderConfig, k relayers, err := chainlink.NewCoreRelayerChainInteroperators(chainlink.InitEVM(testutils.Context(t), f, chainlink.EVMFactoryConfig{ ChainOpts: opts.ChainOpts, CSAETHKeystore: ks, - })) + }, nil)) if err != nil { t.Fatal(err) } diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 12491300bf7..90c21a1747b 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -18,6 +18,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -415,7 +417,11 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn testCtx := testutils.Context(t) // evm alway enabled for backward compatibility - initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitDummy(testCtx, relayerFactory), chainlink.InitEVM(testCtx, relayerFactory, evmOpts)} + telemetryManager := telemetry.NewManager(cfg.TelemetryIngress(), keyStore.CSA(), lggr) + initOps := []chainlink.CoreRelayerChainInitFunc{ + chainlink.InitDummy(testCtx, relayerFactory), + chainlink.InitEVM(testCtx, relayerFactory, evmOpts, telemetryManager), + } if cfg.CosmosEnabled() { cosmosCfg := chainlink.CosmosFactoryConfig{ @@ -463,6 +469,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn CapabilitiesRegistry: capabilitiesRegistry, CapabilitiesDispatcher: dispatcher, CapabilitiesPeerWrapper: peerWrapper, + TelemetryManager: telemetryManager, }) require.NoError(t, err) diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index fd01f72c131..47b01ca13fc 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -3,6 +3,7 @@ package cltest import ( "context" "fmt" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "io" "net/http" "net/http/httptest" @@ -405,6 +406,7 @@ func NewLegacyChainsWithMockChainAndTxManager(t testing.TB, ethClient evmclient. ch.On("ID").Return(scopedCfg.EVM().ChainID()) ch.On("Config").Return(scopedCfg) ch.On("TxManager").Return(txm) + ch.On("HeadBroadcaster").Return(headtracker.NewHeadBroadcaster(ch.Logger())) return NewLegacyChainsWithChain(ch, cfg) } diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 5118bb9ec68..2885a3b56de 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -45,7 +45,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/feeds" "github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2" "github.com/smartcontractkit/chainlink/v2/core/services/gateway" - "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -182,6 +181,7 @@ type ApplicationOpts struct { CapabilitiesRegistry *capabilities.Registry CapabilitiesDispatcher remotetypes.Dispatcher CapabilitiesPeerWrapper p2ptypes.PeerWrapper + TelemetryManager *telemetry.Manager } // NewApplication initializes a new store if one is not already @@ -292,8 +292,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { globalLogger.Info("Nurse service (automatic pprof profiling) is disabled") } - telemetryManager := telemetry.NewManager(cfg.TelemetryIngress(), keyStore.CSA(), globalLogger) - srvcs = append(srvcs, telemetryManager) + srvcs = append(srvcs, opts.TelemetryManager) backupCfg := cfg.Database().Backup() if backupCfg.Mode() != config.DatabaseBackupModeNone && backupCfg.Frequency() > 0 { @@ -323,8 +322,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) { srvcs = append(srvcs, mailMon) srvcs = append(srvcs, relayerChainInterops.Services()...) - headReporter := headreporter.NewHeadReporterService(cfg.HeadReport(), opts.DS, legacyEVMChains, globalLogger, telemetryManager) - srvcs = append(srvcs, headReporter) // Initialize Local Users ORM and Authentication Provider specified in config // BasicAdminUsersORM is initialized and required regardless of separate Authentication Provider @@ -365,7 +362,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) { ) for _, chain := range legacyEVMChains.Slice() { - chain.HeadBroadcaster().Subscribe(headReporter) chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun) } @@ -430,7 +426,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { opts.DS, jobORM, opts.CapabilitiesRegistry, loopRegistrarConfig, - telemetryManager, + opts.TelemetryManager, pipelineRunner, opts.RelayerChainInteroperators), } @@ -479,7 +475,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { keyStore, pipelineRunner, peerWrapper, - telemetryManager, + opts.TelemetryManager, legacyEVMChains, globalLogger, cfg, @@ -502,7 +498,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { pipelineRunner, streamRegistry, peerWrapper, - telemetryManager, + opts.TelemetryManager, legacyEVMChains, globalLogger, ocr2DelegateConfig, diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 60381c0d479..7902a178102 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -7,6 +7,9 @@ import ( "sort" "sync" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + "github.com/smartcontractkit/chainlink-common/pkg/loop" relay "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -113,13 +116,12 @@ func InitDummy(ctx context.Context, factory RelayerFactory) CoreRelayerChainInit } // InitEVM is a option for instantiating evm relayers -func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfig) CoreRelayerChainInitFunc { +func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfig, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) CoreRelayerChainInitFunc { return func(op *CoreRelayerChainInteroperators) (err error) { adapters, err2 := factory.NewEVM(ctx, config) if err2 != nil { return fmt.Errorf("failed to setup EVM relayer: %w", err2) } - legacyMap := make(map[string]legacyevm.Chain) for id, a := range adapters { // adapter is a service @@ -128,6 +130,8 @@ func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfi legacyMap[id.ChainID] = a.Chain() } op.legacyChains.EVMChains = legacyevm.NewLegacyChains(legacyMap, config.AppConfig.EVMConfigs()) + headReporter := headreporter.NewHeadReporterService(config.AppConfig.HeadReport(), config.DS, op.legacyChains.EVMChains, factory.Logger, monitoringEndpointGen, true) + op.srvs = append(op.srvs, headReporter) return nil } } diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go index 5aaf6e16dd4..970ebbe78c6 100644 --- a/core/services/chainlink/relayer_chain_interoperators_test.go +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -218,7 +218,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { DS: db, }, CSAETHKeystore: keyStore, - }), + }, nil), }, expectedEVMChainCnt: 2, expectedEVMNodeCnt: 3, @@ -292,7 +292,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { DS: db, }, CSAETHKeystore: keyStore, - }), + }, nil), chainlink.InitStarknet(testctx, factory, chainlink.StarkNetFactoryConfig{ Keystore: keyStore.StarkNet(), TOMLConfigs: cfg.StarknetConfigs()}), @@ -351,9 +351,14 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { assert.Equal(t, cnt, len(allChainsStats)) assert.Len(t, cr.Slice(), expectedChainCnt) - // should be one relayer per chain and one service per relayer + // should be one relayer per chain assert.Len(t, cr.Slice(), expectedChainCnt) - assert.Len(t, cr.Services(), expectedChainCnt) + // if we have evm chain, then we have head_reporter as extra service + if tt.expectedEVMChainCnt > 0 { + assert.Len(t, cr.Services(), expectedChainCnt+1) + } else { + assert.Len(t, cr.Services(), expectedChainCnt) + } expectedNodeCnt := tt.expectedEVMNodeCnt + tt.expectedCosmosNodeCnt + tt.expectedSolanaNodeCnt + tt.expectedStarknetNodeCnt allNodeStats, cnt, err := cr.NodeStatuses(testctx, 0, 0) diff --git a/core/services/headreporter/head_reporter.go b/core/services/relay/evm/headreporter/head_reporter.go similarity index 78% rename from core/services/headreporter/head_reporter.go rename to core/services/relay/evm/headreporter/head_reporter.go index c2dee2c015d..9f80652fdca 100644 --- a/core/services/headreporter/head_reporter.go +++ b/core/services/relay/evm/headreporter/head_reporter.go @@ -26,14 +26,15 @@ type ( HeadReporterService struct { services.StateMachine - ds sqlutil.DataSource - chains legacyevm.LegacyChainContainer - lggr logger.Logger - newHeads *mailbox.Mailbox[*evmtypes.Head] - chStop services.StopChan - wgDone sync.WaitGroup - reportPeriod time.Duration - reporters []HeadReporter + ds sqlutil.DataSource + chains legacyevm.LegacyChainContainer + lggr logger.Logger + newHeads *mailbox.Mailbox[*evmtypes.Head] + chStop services.StopChan + wgDone sync.WaitGroup + reportPeriod time.Duration + reporters []HeadReporter + unsubscribeFns []func() } ) @@ -58,20 +59,30 @@ func NewHeadReporterServiceWithReporters(ds sqlutil.DataSource, chainContainer l } chStop := make(chan struct{}) return &HeadReporterService{ - ds: ds, - chains: chainContainer, - lggr: lggr.Named("HeadReporterService"), - newHeads: mailbox.NewSingle[*evmtypes.Head](), - chStop: chStop, - wgDone: sync.WaitGroup{}, - reportPeriod: reportPeriod, - reporters: reporters, + ds: ds, + chains: chainContainer, + lggr: lggr.Named("HeadReporterService"), + newHeads: mailbox.NewSingle[*evmtypes.Head](), + chStop: chStop, + wgDone: sync.WaitGroup{}, + reportPeriod: reportPeriod, + reporters: reporters, + unsubscribeFns: nil, + } +} + +func (hrd *HeadReporterService) subscribe() { + hrd.unsubscribeFns = make([]func(), 0, hrd.chains.Len()) + for _, chain := range hrd.chains.Slice() { + _, unsubscribe := chain.HeadBroadcaster().Subscribe(hrd) + hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe) } } func (hrd *HeadReporterService) Start(context.Context) error { return hrd.StartOnce(hrd.Name(), func() error { hrd.wgDone.Add(1) + hrd.subscribe() go hrd.eventLoop() return nil }) diff --git a/core/services/headreporter/head_reporter_test.go b/core/services/relay/evm/headreporter/head_reporter_test.go similarity index 97% rename from core/services/headreporter/head_reporter_test.go rename to core/services/relay/evm/headreporter/head_reporter_test.go index 6effef1ff3c..a08e2678abe 100644 --- a/core/services/headreporter/head_reporter_test.go +++ b/core/services/relay/evm/headreporter/head_reporter_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/jmoiron/sqlx" @@ -26,7 +28,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" ) func newHead() evmtypes.Head { diff --git a/core/services/headreporter/prometheus_reporter.go b/core/services/relay/evm/headreporter/prometheus_reporter.go similarity index 100% rename from core/services/headreporter/prometheus_reporter.go rename to core/services/relay/evm/headreporter/prometheus_reporter.go diff --git a/core/services/headreporter/prometheus_reporter_test.go b/core/services/relay/evm/headreporter/prometheus_reporter_test.go similarity index 97% rename from core/services/headreporter/prometheus_reporter_test.go rename to core/services/relay/evm/headreporter/prometheus_reporter_test.go index 131805cd7a5..7e9240ab95b 100644 --- a/core/services/headreporter/prometheus_reporter_test.go +++ b/core/services/relay/evm/headreporter/prometheus_reporter_test.go @@ -4,6 +4,8 @@ import ( "math/big" "testing" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/stretchr/testify/mock" @@ -13,7 +15,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" ) func Test_PrometheusReporter(t *testing.T) { diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/relay/evm/headreporter/telemetry_reporter.go similarity index 100% rename from core/services/headreporter/telemetry_reporter.go rename to core/services/relay/evm/headreporter/telemetry_reporter.go diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/relay/evm/headreporter/telemetry_reporter_test.go similarity index 98% rename from core/services/headreporter/telemetry_reporter_test.go rename to core/services/relay/evm/headreporter/telemetry_reporter_test.go index bfb24d8ed01..2f5f95c0c8d 100644 --- a/core/services/headreporter/telemetry_reporter_test.go +++ b/core/services/relay/evm/headreporter/telemetry_reporter_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -16,7 +18,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" mocks2 "github.com/smartcontractkit/chainlink/v2/core/services/telemetry/mocks" From d455db0871509029703fdf6d997d91c0d99749e4 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Tue, 30 Jul 2024 11:15:19 +0100 Subject: [PATCH 04/21] go generate --- .mockery.yaml | 11 ++-- core/internal/cltest/mocks.go | 3 +- core/internal/mocks/head_reporter.go | 65 +++++++++++++++++++ .../chainlink/mocks/general_config.go | 27 ++++++++ .../relay/evm/headreporter/head_reporter.go | 1 - .../evm/headreporter/head_reporter_test.go | 6 +- 6 files changed, 102 insertions(+), 11 deletions(-) diff --git a/.mockery.yaml b/.mockery.yaml index abb3105b136..b309dbabd3a 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -262,11 +262,6 @@ packages: ORM: Runner: PipelineParamUnmarshaler: - github.com/smartcontractkit/chainlink/v2/core/services/promreporter: - config: - dir: core/internal/mocks - interfaces: - PrometheusBackend: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm: interfaces: BatchCaller: @@ -283,6 +278,12 @@ packages: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types: interfaces: LogPollerWrapper: + github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter: + config: + dir: core/internal/mocks + interfaces: + HeadReporter: + PrometheusBackend: github.com/smartcontractkit/chainlink/v2/core/services/s4: interfaces: ORM: diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index 47b01ca13fc..7fa977d0d45 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -3,7 +3,6 @@ package cltest import ( "context" "fmt" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "io" "net/http" "net/http/httptest" @@ -11,6 +10,8 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" diff --git a/core/internal/mocks/head_reporter.go b/core/internal/mocks/head_reporter.go index 49e4e7f491d..1a81b21bb13 100644 --- a/core/internal/mocks/head_reporter.go +++ b/core/internal/mocks/head_reporter.go @@ -15,6 +15,14 @@ type HeadReporter struct { mock.Mock } +type HeadReporter_Expecter struct { + mock *mock.Mock +} + +func (_m *HeadReporter) EXPECT() *HeadReporter_Expecter { + return &HeadReporter_Expecter{mock: &_m.Mock} +} + // ReportNewHead provides a mock function with given fields: ctx, head func (_m *HeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { ret := _m.Called(ctx, head) @@ -33,6 +41,35 @@ func (_m *HeadReporter) ReportNewHead(ctx context.Context, head *types.Head) err return r0 } +// HeadReporter_ReportNewHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportNewHead' +type HeadReporter_ReportNewHead_Call struct { + *mock.Call +} + +// ReportNewHead is a helper method to define mock.On call +// - ctx context.Context +// - head *types.Head +func (_e *HeadReporter_Expecter) ReportNewHead(ctx interface{}, head interface{}) *HeadReporter_ReportNewHead_Call { + return &HeadReporter_ReportNewHead_Call{Call: _e.mock.On("ReportNewHead", ctx, head)} +} + +func (_c *HeadReporter_ReportNewHead_Call) Run(run func(ctx context.Context, head *types.Head)) *HeadReporter_ReportNewHead_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*types.Head)) + }) + return _c +} + +func (_c *HeadReporter_ReportNewHead_Call) Return(_a0 error) *HeadReporter_ReportNewHead_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *HeadReporter_ReportNewHead_Call) RunAndReturn(run func(context.Context, *types.Head) error) *HeadReporter_ReportNewHead_Call { + _c.Call.Return(run) + return _c +} + // ReportPeriodic provides a mock function with given fields: ctx func (_m *HeadReporter) ReportPeriodic(ctx context.Context) error { ret := _m.Called(ctx) @@ -51,6 +88,34 @@ func (_m *HeadReporter) ReportPeriodic(ctx context.Context) error { return r0 } +// HeadReporter_ReportPeriodic_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportPeriodic' +type HeadReporter_ReportPeriodic_Call struct { + *mock.Call +} + +// ReportPeriodic is a helper method to define mock.On call +// - ctx context.Context +func (_e *HeadReporter_Expecter) ReportPeriodic(ctx interface{}) *HeadReporter_ReportPeriodic_Call { + return &HeadReporter_ReportPeriodic_Call{Call: _e.mock.On("ReportPeriodic", ctx)} +} + +func (_c *HeadReporter_ReportPeriodic_Call) Run(run func(ctx context.Context)) *HeadReporter_ReportPeriodic_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *HeadReporter_ReportPeriodic_Call) Return(_a0 error) *HeadReporter_ReportPeriodic_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *HeadReporter_ReportPeriodic_Call) RunAndReturn(run func(context.Context) error) *HeadReporter_ReportPeriodic_Call { + _c.Call.Return(run) + return _c +} + // NewHeadReporter creates a new instance of HeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewHeadReporter(t interface { diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index ae2e73768b6..f04ff40c566 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -712,6 +712,33 @@ func (_m *GeneralConfig) HeadReport() config.HeadReport { return r0 } +// GeneralConfig_HeadReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HeadReport' +type GeneralConfig_HeadReport_Call struct { + *mock.Call +} + +// HeadReport is a helper method to define mock.On call +func (_e *GeneralConfig_Expecter) HeadReport() *GeneralConfig_HeadReport_Call { + return &GeneralConfig_HeadReport_Call{Call: _e.mock.On("HeadReport")} +} + +func (_c *GeneralConfig_HeadReport_Call) Run(run func()) *GeneralConfig_HeadReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *GeneralConfig_HeadReport_Call) Return(_a0 config.HeadReport) *GeneralConfig_HeadReport_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GeneralConfig_HeadReport_Call) RunAndReturn(run func() config.HeadReport) *GeneralConfig_HeadReport_Call { + _c.Call.Return(run) + return _c +} + // Insecure provides a mock function with given fields: func (_m *GeneralConfig) Insecure() config.Insecure { ret := _m.Called() diff --git a/core/services/relay/evm/headreporter/head_reporter.go b/core/services/relay/evm/headreporter/head_reporter.go index 9f80652fdca..6d215866ed2 100644 --- a/core/services/relay/evm/headreporter/head_reporter.go +++ b/core/services/relay/evm/headreporter/head_reporter.go @@ -17,7 +17,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" ) -//go:generate mockery --quiet --name HeadReporter --output ../../internal/mocks/ --case=underscore type ( HeadReporter interface { ReportNewHead(ctx context.Context, head *evmtypes.Head) error diff --git a/core/services/relay/evm/headreporter/head_reporter_test.go b/core/services/relay/evm/headreporter/head_reporter_test.go index a08e2678abe..0e437625f06 100644 --- a/core/services/relay/evm/headreporter/head_reporter_test.go +++ b/core/services/relay/evm/headreporter/head_reporter_test.go @@ -5,10 +5,6 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" - "github.com/jmoiron/sqlx" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" @@ -24,10 +20,12 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" ) func newHead() evmtypes.Head { From 3da39023389371d087664d9d6494a2809dfac795 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Tue, 30 Jul 2024 12:43:16 +0100 Subject: [PATCH 05/21] move config --- .mockery.yaml | 5 ++ common/headtracker/types/config.go | 1 + .../evm/config/chain_scoped_head_tracker.go | 4 + core/chains/evm/config/config.go | 1 + core/chains/evm/config/toml/config.go | 4 + .../evm/config/toml/defaults/fallback.toml | 1 + .../chains/evm/headtracker/head_saver_test.go | 3 + core/cmd/shell.go | 3 +- core/config/app_config.go | 1 - core/config/docs/chains-evm.toml | 2 + core/config/docs/core.toml | 4 - core/config/head_report_config.go | 5 -- core/config/toml/types.go | 12 --- core/internal/cltest/cltest.go | 3 +- core/internal/cltest/mocks.go | 8 +- .../mocks/monitoring_endpoint_generator.go | 88 +++++++++++++++++++ core/services/chainlink/config_general.go | 6 -- .../services/chainlink/config_general_test.go | 1 - core/services/chainlink/config_head_report.go | 13 --- .../chainlink/config_head_report_test.go | 18 ---- core/services/chainlink/config_test.go | 8 +- .../chainlink/mocks/general_config.go | 47 ---------- .../chainlink/relayer_chain_interoperators.go | 2 +- .../testdata/config-empty-effective.toml | 3 - .../chainlink/testdata/config-full.toml | 4 +- .../config-multi-chain-effective.toml | 6 +- .../relay/evm/headreporter/head_reporter.go | 20 +++-- .../evm/headreporter/telemetry_reporter.go | 3 +- .../headreporter/telemetry_reporter_test.go | 12 ++- core/services/telemetry/common.go | 1 - .../mocks/monitoring_endpoint_generator.go | 49 ----------- .../testdata/config-empty-effective.toml | 3 - core/web/resolver/testdata/config-full.toml | 4 +- .../config-multi-chain-effective.toml | 6 +- docs/CONFIG.md | 79 ++++++++++++++--- testdata/scripts/node/validate/default.txtar | 3 - .../disk-based-logging-disabled.txtar | 4 +- .../validate/disk-based-logging-no-dir.txtar | 4 +- .../node/validate/disk-based-logging.txtar | 4 +- .../node/validate/invalid-ocr-p2p.txtar | 3 - testdata/scripts/node/validate/invalid.txtar | 4 +- testdata/scripts/node/validate/valid.txtar | 4 +- testdata/scripts/node/validate/warnings.txtar | 3 - 43 files changed, 216 insertions(+), 243 deletions(-) delete mode 100644 core/config/head_report_config.go create mode 100644 core/internal/mocks/monitoring_endpoint_generator.go delete mode 100644 core/services/chainlink/config_head_report.go delete mode 100644 core/services/chainlink/config_head_report_test.go delete mode 100644 core/services/telemetry/mocks/monitoring_endpoint_generator.go diff --git a/.mockery.yaml b/.mockery.yaml index b309dbabd3a..19f37586cd0 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -302,6 +302,11 @@ packages: interfaces: Config: FeeConfig: + github.com/smartcontractkit/chainlink/v2/core/services/telemetry: + config: + dir: "{{ .InterfaceDir }}/../../internal/mocks" + interfaces: + MonitoringEndpointGenerator: github.com/smartcontractkit/chainlink/v2/core/services/webhook: interfaces: ExternalInitiatorManager: diff --git a/common/headtracker/types/config.go b/common/headtracker/types/config.go index 06ad93d39d2..289d2bc502c 100644 --- a/common/headtracker/types/config.go +++ b/common/headtracker/types/config.go @@ -15,4 +15,5 @@ type HeadTrackerConfig interface { SamplingInterval() time.Duration FinalityTagBypass() bool MaxAllowedFinalityDepth() uint32 + HeadTelemetryEnabled() bool } diff --git a/core/chains/evm/config/chain_scoped_head_tracker.go b/core/chains/evm/config/chain_scoped_head_tracker.go index 8bc1ff188a7..de6e19e9d6e 100644 --- a/core/chains/evm/config/chain_scoped_head_tracker.go +++ b/core/chains/evm/config/chain_scoped_head_tracker.go @@ -29,3 +29,7 @@ func (h *headTrackerConfig) FinalityTagBypass() bool { func (h *headTrackerConfig) MaxAllowedFinalityDepth() uint32 { return *h.c.MaxAllowedFinalityDepth } + +func (h *headTrackerConfig) HeadTelemetryEnabled() bool { + return *h.c.HeadTelemetryEnabled +} diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 3ccdfeea8b8..e6265c40f55 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -75,6 +75,7 @@ type HeadTracker interface { SamplingInterval() time.Duration FinalityTagBypass() bool MaxAllowedFinalityDepth() uint32 + HeadTelemetryEnabled() bool } type BalanceMonitor interface { diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 2cb29d97696..7f7dc0c1939 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -748,6 +748,7 @@ type HeadTracker struct { SamplingInterval *commonconfig.Duration MaxAllowedFinalityDepth *uint32 FinalityTagBypass *bool + HeadTelemetryEnabled *bool } func (t *HeadTracker) setFrom(f *HeadTracker) { @@ -766,6 +767,9 @@ func (t *HeadTracker) setFrom(f *HeadTracker) { if v := f.FinalityTagBypass; v != nil { t.FinalityTagBypass = v } + if v := f.HeadTelemetryEnabled; v != nil { + t.HeadTelemetryEnabled = v + } } func (t *HeadTracker) ValidateConfig() (err error) { diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index a47e56bc918..2e26c9466a2 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -61,6 +61,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' FinalityTagBypass = true MaxAllowedFinalityDepth = 10000 +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 diff --git a/core/chains/evm/headtracker/head_saver_test.go b/core/chains/evm/headtracker/head_saver_test.go index 43e79235e90..c87e1830d91 100644 --- a/core/chains/evm/headtracker/head_saver_test.go +++ b/core/chains/evm/headtracker/head_saver_test.go @@ -42,6 +42,9 @@ func (h *headTrackerConfig) FinalityTagBypass() bool { func (h *headTrackerConfig) MaxAllowedFinalityDepth() uint32 { return 10000 } +func (h *headTrackerConfig) HeadTelemetryEnabled() bool { + return false +} type config struct { finalityDepth uint32 diff --git a/core/cmd/shell.go b/core/cmd/shell.go index e146115ba04..744c768aad0 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -19,8 +19,6 @@ import ( "sync" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/Depado/ginprom" "github.com/Masterminds/semver/v3" "github.com/getsentry/sentry-go" @@ -48,6 +46,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/periodicbackup" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/core/services/versioning" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" "github.com/smartcontractkit/chainlink/v2/core/sessions" diff --git a/core/config/app_config.go b/core/config/app_config.go index fe877d110ab..112e242636f 100644 --- a/core/config/app_config.go +++ b/core/config/app_config.go @@ -53,7 +53,6 @@ type AppConfig interface { Pyroscope() Pyroscope Sentry() Sentry TelemetryIngress() TelemetryIngress - HeadReport() HeadReport Threshold() Threshold WebServer() WebServer Tracing() Tracing diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 444804b3826..c29c0ce04ed 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -334,6 +334,8 @@ FinalityTagBypass = true # Default # If actual finality depth exceeds this number, HeadTracker aborts backfill and returns an error. # Has no effect if `FinalityTagsEnabled` = false MaxAllowedFinalityDepth = 10000 # Default +# HeadTelemetryEnabled controls if it collects information about new blocks from blockchain +HeadTelemetryEnabled = false # Default [[EVM.KeySpecific]] # Key is the account to apply these settings to diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index e45a7cd3841..d0960779c6c 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -651,7 +651,3 @@ TransmitQueueMaxSize = 10_000 # Default # when sending a message to the mercury server, before aborting and considering # the transmission to be failed. TransmitTimeout = "5s" # Default - -[HeadReport] -# TelemetryEnabled controls if it collects information about new blocks from blockchain -TelemetryEnabled = false # Default diff --git a/core/config/head_report_config.go b/core/config/head_report_config.go deleted file mode 100644 index 9f4ae85eb6c..00000000000 --- a/core/config/head_report_config.go +++ /dev/null @@ -1,5 +0,0 @@ -package config - -type HeadReport interface { - TelemetryEnabled() bool -} diff --git a/core/config/toml/types.go b/core/config/toml/types.go index a503720ea9e..0c91ddd81a9 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -56,7 +56,6 @@ type Core struct { Insecure Insecure `toml:",omitempty"` Tracing Tracing `toml:",omitempty"` Mercury Mercury `toml:",omitempty"` - HeadReport HeadReport `toml:",omitempty"` Capabilities Capabilities `toml:",omitempty"` } @@ -77,7 +76,6 @@ func (c *Core) SetFrom(f *Core) { c.TelemetryIngress.setFrom(&f.TelemetryIngress) c.AuditLogger.SetFrom(&f.AuditLogger) c.Log.setFrom(&f.Log) - c.HeadReport.setFrom(&f.HeadReport) c.WebServer.setFrom(&f.WebServer) c.JobPipeline.setFrom(&f.JobPipeline) @@ -487,16 +485,6 @@ func (t *TelemetryIngress) setFrom(f *TelemetryIngress) { } } -type HeadReport struct { - TelemetryEnabled *bool -} - -func (t *HeadReport) setFrom(f *HeadReport) { - if v := f.TelemetryEnabled; v != nil { - t.TelemetryEnabled = v - } -} - type AuditLogger struct { Enabled *bool ForwardToUrl *commonconfig.URL diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 90c21a1747b..b34835eec3f 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -18,8 +18,6 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -86,6 +84,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" clsessions "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/static" diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index 7fa977d0d45..25273380272 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -10,18 +10,16 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/jmoiron/sqlx" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" "github.com/smartcontractkit/chainlink/v2/core/cmd" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" diff --git a/core/internal/mocks/monitoring_endpoint_generator.go b/core/internal/mocks/monitoring_endpoint_generator.go new file mode 100644 index 00000000000..1384e2e2a43 --- /dev/null +++ b/core/internal/mocks/monitoring_endpoint_generator.go @@ -0,0 +1,88 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + commontypes "github.com/smartcontractkit/libocr/commontypes" + mock "github.com/stretchr/testify/mock" + + synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" +) + +// MonitoringEndpointGenerator is an autogenerated mock type for the MonitoringEndpointGenerator type +type MonitoringEndpointGenerator struct { + mock.Mock +} + +type MonitoringEndpointGenerator_Expecter struct { + mock *mock.Mock +} + +func (_m *MonitoringEndpointGenerator) EXPECT() *MonitoringEndpointGenerator_Expecter { + return &MonitoringEndpointGenerator_Expecter{mock: &_m.Mock} +} + +// GenMonitoringEndpoint provides a mock function with given fields: network, chainID, contractID, telemType +func (_m *MonitoringEndpointGenerator) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { + ret := _m.Called(network, chainID, contractID, telemType) + + if len(ret) == 0 { + panic("no return value specified for GenMonitoringEndpoint") + } + + var r0 commontypes.MonitoringEndpoint + if rf, ok := ret.Get(0).(func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint); ok { + r0 = rf(network, chainID, contractID, telemType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(commontypes.MonitoringEndpoint) + } + } + + return r0 +} + +// MonitoringEndpointGenerator_GenMonitoringEndpoint_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenMonitoringEndpoint' +type MonitoringEndpointGenerator_GenMonitoringEndpoint_Call struct { + *mock.Call +} + +// GenMonitoringEndpoint is a helper method to define mock.On call +// - network string +// - chainID string +// - contractID string +// - telemType synchronization.TelemetryType +func (_e *MonitoringEndpointGenerator_Expecter) GenMonitoringEndpoint(network interface{}, chainID interface{}, contractID interface{}, telemType interface{}) *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + return &MonitoringEndpointGenerator_GenMonitoringEndpoint_Call{Call: _e.mock.On("GenMonitoringEndpoint", network, chainID, contractID, telemType)} +} + +func (_c *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call) Run(run func(network string, chainID string, contractID string, telemType synchronization.TelemetryType)) *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(string), args[3].(synchronization.TelemetryType)) + }) + return _c +} + +func (_c *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call) Return(_a0 commontypes.MonitoringEndpoint) *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call) RunAndReturn(run func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint) *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Return(run) + return _c +} + +// NewMonitoringEndpointGenerator creates a new instance of MonitoringEndpointGenerator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMonitoringEndpointGenerator(t interface { + mock.TestingT + Cleanup(func()) +}) *MonitoringEndpointGenerator { + mock := &MonitoringEndpointGenerator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index abdd48d7592..5b6b839fb5e 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -483,12 +483,6 @@ func (g *generalConfig) RootDir() string { return h } -func (g *generalConfig) HeadReport() coreconfig.HeadReport { - return &headReport{ - h: g.c.HeadReport, - } -} - func (g *generalConfig) TelemetryIngress() coreconfig.TelemetryIngress { return &telemetryIngressConfig{ c: g.c.TelemetryIngress, diff --git a/core/services/chainlink/config_general_test.go b/core/services/chainlink/config_general_test.go index 6247ebd91c8..29393ee0fdd 100644 --- a/core/services/chainlink/config_general_test.go +++ b/core/services/chainlink/config_general_test.go @@ -30,7 +30,6 @@ func TestTOMLGeneralConfig_Defaults(t *testing.T) { assert.False(t, config.StarkNetEnabled()) assert.Equal(t, false, config.JobPipeline().ExternalInitiatorsEnabled()) assert.Equal(t, 15*time.Minute, config.WebServer().SessionTimeout().Duration()) - assert.Equal(t, false, config.HeadReport().TelemetryEnabled()) } func TestTOMLGeneralConfig_InsecureConfig(t *testing.T) { diff --git a/core/services/chainlink/config_head_report.go b/core/services/chainlink/config_head_report.go deleted file mode 100644 index e6e292938d9..00000000000 --- a/core/services/chainlink/config_head_report.go +++ /dev/null @@ -1,13 +0,0 @@ -package chainlink - -import ( - "github.com/smartcontractkit/chainlink/v2/core/config/toml" -) - -type headReport struct { - h toml.HeadReport -} - -func (h headReport) TelemetryEnabled() bool { - return *h.h.TelemetryEnabled -} diff --git a/core/services/chainlink/config_head_report_test.go b/core/services/chainlink/config_head_report_test.go deleted file mode 100644 index 1840c4f578b..00000000000 --- a/core/services/chainlink/config_head_report_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package chainlink - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestHeadReportConfig(t *testing.T) { - opts := GeneralConfigOpts{ - ConfigStrings: []string{fullTOML}, - } - cfg, err := opts.New() - require.NoError(t, err) - - hr := cfg.HeadReport() - require.True(t, hr.TelemetryEnabled()) -} diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index bd75e92b23b..2d6794ece7e 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -587,6 +587,7 @@ func TestConfig_Marshal(t *testing.T) { SamplingInterval: &hour, FinalityTagBypass: ptr[bool](false), MaxAllowedFinalityDepth: ptr[uint32](1500), + HeadTelemetryEnabled: ptr[bool](true), }, NodePool: evmcfg.NodePool{ @@ -733,9 +734,6 @@ func TestConfig_Marshal(t *testing.T) { }, VerboseLogging: ptr(true), } - full.HeadReport = toml.HeadReport{ - TelemetryEnabled: ptr(true), - } for _, tt := range []struct { name string config Config @@ -1057,6 +1055,7 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 1500 FinalityTagBypass = false +HeadTelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' @@ -1206,9 +1205,6 @@ CertFile = '/path/to/cert.pem' [Mercury.Transmitter] TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' -`}, - {"HeadReport", Config{Core: toml.Core{HeadReport: full.HeadReport}}, `[HeadReport] -TelemetryEnabled = true `}, {"full", full, fullTOML}, {"multi-chain", multiChain, multiChainTOML}, diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index f04ff40c566..c42ed5c7014 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -692,53 +692,6 @@ func (_c *GeneralConfig_FluxMonitor_Call) RunAndReturn(run func() config.FluxMon return _c } -// HeadReport provides a mock function with given fields: -func (_m *GeneralConfig) HeadReport() config.HeadReport { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for HeadReport") - } - - var r0 config.HeadReport - if rf, ok := ret.Get(0).(func() config.HeadReport); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(config.HeadReport) - } - } - - return r0 -} - -// GeneralConfig_HeadReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HeadReport' -type GeneralConfig_HeadReport_Call struct { - *mock.Call -} - -// HeadReport is a helper method to define mock.On call -func (_e *GeneralConfig_Expecter) HeadReport() *GeneralConfig_HeadReport_Call { - return &GeneralConfig_HeadReport_Call{Call: _e.mock.On("HeadReport")} -} - -func (_c *GeneralConfig_HeadReport_Call) Run(run func()) *GeneralConfig_HeadReport_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *GeneralConfig_HeadReport_Call) Return(_a0 config.HeadReport) *GeneralConfig_HeadReport_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *GeneralConfig_HeadReport_Call) RunAndReturn(run func() config.HeadReport) *GeneralConfig_HeadReport_Call { - _c.Call.Return(run) - return _c -} - // Insecure provides a mock function with given fields: func (_m *GeneralConfig) Insecure() config.Insecure { ret := _m.Called() diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 7902a178102..6c00213c971 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -130,7 +130,7 @@ func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfi legacyMap[id.ChainID] = a.Chain() } op.legacyChains.EVMChains = legacyevm.NewLegacyChains(legacyMap, config.AppConfig.EVMConfigs()) - headReporter := headreporter.NewHeadReporterService(config.AppConfig.HeadReport(), config.DS, op.legacyChains.EVMChains, factory.Logger, monitoringEndpointGen, true) + headReporter := headreporter.NewHeadReporterService(config.DS, op.legacyChains.EVMChains, factory.Logger, monitoringEndpointGen) op.srvs = append(op.srvs, headReporter) return nil } diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index 93a5e509ab1..f1325d824ea 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -237,9 +237,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index b2c342f33c7..40ecf8060d3 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -247,9 +247,6 @@ CertFile = '/path/to/cert.pem' TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 @@ -350,6 +347,7 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 1500 FinalityTagBypass = false +HeadTelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index f97e31f5b7d..81e6fa0dcea 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -237,9 +237,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -327,6 +324,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -427,6 +425,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -521,6 +520,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/core/services/relay/evm/headreporter/head_reporter.go b/core/services/relay/evm/headreporter/head_reporter.go index 6d215866ed2..fe2ade6c199 100644 --- a/core/services/relay/evm/headreporter/head_reporter.go +++ b/core/services/relay/evm/headreporter/head_reporter.go @@ -6,7 +6,6 @@ import ( "time" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -37,11 +36,18 @@ type ( } ) -func NewHeadReporterService(config config.HeadReport, ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, opts ...interface{}) *HeadReporterService { +func NewHeadReporterService(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, opts ...interface{}) *HeadReporterService { reporters := make([]HeadReporter, 1, 2) reporters[0] = NewPrometheusReporter(ds, chainContainer, lggr, opts) - if config.TelemetryEnabled() { - reporters = append(reporters, NewTelemetryReporter(chainContainer, lggr, monitoringEndpointGen)) + telemetryEnabled := false + for _, chain := range chainContainer.Slice() { + if chain.Config().EVM().HeadTracker().HeadTelemetryEnabled() { + telemetryEnabled = true + break + } + } + if telemetryEnabled { + reporters = append(reporters, NewTelemetryReporter(chainContainer, monitoringEndpointGen)) } return NewHeadReporterServiceWithReporters(ds, chainContainer, lggr, reporters, opts) } @@ -73,8 +79,10 @@ func NewHeadReporterServiceWithReporters(ds sqlutil.DataSource, chainContainer l func (hrd *HeadReporterService) subscribe() { hrd.unsubscribeFns = make([]func(), 0, hrd.chains.Len()) for _, chain := range hrd.chains.Slice() { - _, unsubscribe := chain.HeadBroadcaster().Subscribe(hrd) - hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe) + if chain.Config().EVM().HeadTracker().HeadTelemetryEnabled() { + _, unsubscribe := chain.HeadBroadcaster().Subscribe(hrd) + hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe) + } } } diff --git a/core/services/relay/evm/headreporter/telemetry_reporter.go b/core/services/relay/evm/headreporter/telemetry_reporter.go index 241296a7e46..e3d8e096084 100644 --- a/core/services/relay/evm/headreporter/telemetry_reporter.go +++ b/core/services/relay/evm/headreporter/telemetry_reporter.go @@ -10,7 +10,6 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" @@ -22,7 +21,7 @@ type ( } ) -func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { +func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { endpoints := make(map[uint64]commontypes.MonitoringEndpoint) for _, chain := range chainContainer.Slice() { endpoints[chain.ID().Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chain.ID().String(), "", synchronization.HeadReport) diff --git a/core/services/relay/evm/headreporter/telemetry_reporter_test.go b/core/services/relay/evm/headreporter/telemetry_reporter_test.go index 2f5f95c0c8d..103a2b27f92 100644 --- a/core/services/relay/evm/headreporter/telemetry_reporter_test.go +++ b/core/services/relay/evm/headreporter/telemetry_reporter_test.go @@ -5,8 +5,6 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -16,11 +14,11 @@ import ( ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" + mocks2 "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" - mocks2 "github.com/smartcontractkit/chainlink/v2/core/services/telemetry/mocks" ) type IngressAgent struct { @@ -55,7 +53,7 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(ingressAgent) - reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) head := evmtypes.Head{ Number: 42, @@ -102,7 +100,7 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(ingressAgent) - reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) head := evmtypes.Head{ Number: 42, @@ -137,7 +135,7 @@ func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(nil) - reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) head := evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(100)} diff --git a/core/services/telemetry/common.go b/core/services/telemetry/common.go index 1ccd9674589..37a92f16c6d 100644 --- a/core/services/telemetry/common.go +++ b/core/services/telemetry/common.go @@ -6,7 +6,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" ) -//go:generate mockery --quiet --name MonitoringEndpointGenerator --output ./mocks --case=underscore type MonitoringEndpointGenerator interface { GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) ocrtypes.MonitoringEndpoint } diff --git a/core/services/telemetry/mocks/monitoring_endpoint_generator.go b/core/services/telemetry/mocks/monitoring_endpoint_generator.go deleted file mode 100644 index 717654f404f..00000000000 --- a/core/services/telemetry/mocks/monitoring_endpoint_generator.go +++ /dev/null @@ -1,49 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - commontypes "github.com/smartcontractkit/libocr/commontypes" - mock "github.com/stretchr/testify/mock" - - synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" -) - -// MonitoringEndpointGenerator is an autogenerated mock type for the MonitoringEndpointGenerator type -type MonitoringEndpointGenerator struct { - mock.Mock -} - -// GenMonitoringEndpoint provides a mock function with given fields: network, chainID, contractID, telemType -func (_m *MonitoringEndpointGenerator) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { - ret := _m.Called(network, chainID, contractID, telemType) - - if len(ret) == 0 { - panic("no return value specified for GenMonitoringEndpoint") - } - - var r0 commontypes.MonitoringEndpoint - if rf, ok := ret.Get(0).(func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint); ok { - r0 = rf(network, chainID, contractID, telemType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(commontypes.MonitoringEndpoint) - } - } - - return r0 -} - -// NewMonitoringEndpointGenerator creates a new instance of MonitoringEndpointGenerator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMonitoringEndpointGenerator(t interface { - mock.TestingT - Cleanup(func()) -}) *MonitoringEndpointGenerator { - mock := &MonitoringEndpointGenerator{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index 93a5e509ab1..f1325d824ea 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -237,9 +237,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index ab6d0ab8447..62dfb47d7e0 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -247,9 +247,6 @@ CertFile = '' TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 @@ -349,6 +346,7 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 5bf08c78346..8059832ff6f 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -237,9 +237,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -327,6 +324,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -427,6 +425,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -521,6 +520,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index c2270599d00..bcf7267e937 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1768,19 +1768,6 @@ TransmitTimeout controls how long the transmitter will wait for a response when sending a message to the mercury server, before aborting and considering the transmission to be failed. -## HeadReport -```toml -[HeadReport] -TelemetryEnabled = false # Default -``` - - -### TelemetryEnabled -```toml -TelemetryEnabled = false # Default -``` -TelemetryEnabled controls if it collects information about new blocks from blockchain - ## EVM EVM defaults depend on ChainID: @@ -1852,6 +1839,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -1946,6 +1934,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2040,6 +2029,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2134,6 +2124,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2229,6 +2220,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2323,6 +2315,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2417,6 +2410,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2512,6 +2506,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2606,6 +2601,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2699,6 +2695,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2792,6 +2789,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2886,6 +2884,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2981,6 +2980,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3075,6 +3075,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3169,6 +3170,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3263,6 +3265,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3357,6 +3360,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3451,6 +3455,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3545,6 +3550,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3639,6 +3645,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3733,6 +3740,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3827,6 +3835,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3922,6 +3931,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4016,6 +4026,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4109,6 +4120,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4203,6 +4215,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4297,6 +4310,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4391,6 +4405,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4485,6 +4500,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4578,6 +4594,7 @@ MaxBufferSize = 100 SamplingInterval = '0s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4672,6 +4689,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4766,6 +4784,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4860,6 +4879,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4954,6 +4974,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5047,6 +5068,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5141,6 +5163,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5235,6 +5258,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5520,6 +5544,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5614,6 +5639,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5708,6 +5734,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5802,6 +5829,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5896,6 +5924,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5989,6 +6018,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6082,6 +6112,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6175,6 +6206,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6269,6 +6301,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6363,6 +6396,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6456,6 +6490,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6550,6 +6585,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6644,6 +6680,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6739,6 +6776,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6834,6 +6872,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6928,6 +6967,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7022,6 +7062,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7116,6 +7157,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7210,6 +7252,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7304,6 +7347,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7398,6 +7442,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7492,6 +7537,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -8147,6 +8193,7 @@ MaxBufferSize = 3 # Default SamplingInterval = '1s' # Default FinalityTagBypass = true # Default MaxAllowedFinalityDepth = 10000 # Default +HeadTelemetryEnabled = false # Default ``` The head tracker continually listens for new heads from the chain. @@ -8193,6 +8240,12 @@ MaxAllowedFinalityDepth - defines maximum number of blocks between the most rece If actual finality depth exceeds this number, HeadTracker aborts backfill and returns an error. Has no effect if `FinalityTagsEnabled` = false +### HeadTelemetryEnabled +```toml +HeadTelemetryEnabled = false # Default +``` +HeadTelemetryEnabled controls if it collects information about new blocks from blockchain + ## EVM.KeySpecific ```toml [[EVM.KeySpecific]] diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index 10897c897c7..ff8b4889c49 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -249,9 +249,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index c25e5662daf..9172986830b 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -293,9 +293,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -383,6 +380,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 9b7410df901..98b97fd98df 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -293,9 +293,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -383,6 +380,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 302700174b5..bcca7c4b453 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -293,9 +293,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -383,6 +380,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 6fa9ca932a8..0cdf001eccd 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -278,9 +278,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 99410d91078..b93a7454887 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -283,9 +283,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -373,6 +370,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index d11377ec74a..eb37b63342b 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -290,9 +290,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -380,6 +377,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true +HeadTelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index 9d27734d058..dea40ec8da0 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -272,9 +272,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 From ce0f9e2326c7c9fc9be6e65fea03dfea7370ea63 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 31 Jul 2024 21:13:16 -0500 Subject: [PATCH 06/21] simplify --- .mockery.yaml | 5 +- core/cmd/shell.go | 8 +- core/cmd/shell_local_test.go | 2 +- core/internal/cltest/cltest.go | 8 +- core/internal/mocks/head_reporter.go | 131 ----------- core/internal/mocks/prometheus_backend.go | 204 ------------------ core/services/chainlink/application.go | 31 ++- .../chainlink/relayer_chain_interoperators.go | 9 +- .../relayer_chain_interoperators_test.go | 4 +- .../relay/evm/headreporter/head_reporter.go | 61 +----- .../evm/headreporter/head_reporter_test.go | 64 +----- .../relay/evm/headreporter/helper_test.go | 5 + .../headreporter/mock_head_reporter_test.go | 130 +++++++++++ .../mock_prometheus_backend_test.go | 204 ++++++++++++++++++ .../evm/headreporter/prometheus_reporter.go | 14 +- .../headreporter/prometheus_reporter_test.go | 73 +++++-- 16 files changed, 456 insertions(+), 497 deletions(-) delete mode 100644 core/internal/mocks/head_reporter.go delete mode 100644 core/internal/mocks/prometheus_backend.go create mode 100644 core/services/relay/evm/headreporter/helper_test.go create mode 100644 core/services/relay/evm/headreporter/mock_head_reporter_test.go create mode 100644 core/services/relay/evm/headreporter/mock_prometheus_backend_test.go diff --git a/.mockery.yaml b/.mockery.yaml index 19f37586cd0..59174bacb5b 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -280,7 +280,10 @@ packages: LogPollerWrapper: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter: config: - dir: core/internal/mocks + dir: "{{ .InterfaceDir }}" + filename: "mock_{{ .InterfaceName | snakecase }}_test.go" + inpackage: true + mockname: "Mock{{ .InterfaceName | camelcase }}" interfaces: HeadReporter: PrometheusBackend: diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 744c768aad0..3fb5cc5e9a8 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -46,7 +46,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/periodicbackup" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/cache" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/core/services/versioning" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" "github.com/smartcontractkit/chainlink/v2/core/sessions" @@ -184,13 +183,9 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G MercuryTransmitter: cfg.Mercury().Transmitter(), } - telemetryManager := telemetry.NewManager(cfg.TelemetryIngress(), keyStore.CSA(), appLggr) // evm always enabled for backward compatibility // TODO BCF-2510 this needs to change in order to clear the path for EVM extraction - initOps := []chainlink.CoreRelayerChainInitFunc{ - chainlink.InitDummy(ctx, relayerFactory), - chainlink.InitEVM(ctx, relayerFactory, evmFactoryCfg, telemetryManager), - } + initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitDummy(ctx, relayerFactory), chainlink.InitEVM(ctx, relayerFactory, evmFactoryCfg)} if cfg.CosmosEnabled() { cosmosCfg := chainlink.CosmosFactoryConfig{ @@ -246,7 +241,6 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G GRPCOpts: grpcOpts, MercuryPool: mercuryPool, CapabilitiesRegistry: capabilitiesRegistry, - TelemetryManager: telemetryManager, }) } diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 6ec561f1bed..8ed48dcaa20 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -52,7 +52,7 @@ func genTestEVMRelayers(t *testing.T, opts legacyevm.ChainRelayExtenderConfig, k relayers, err := chainlink.NewCoreRelayerChainInteroperators(chainlink.InitEVM(testutils.Context(t), f, chainlink.EVMFactoryConfig{ ChainOpts: opts.ChainOpts, CSAETHKeystore: ks, - }, nil)) + })) if err != nil { t.Fatal(err) } diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index b34835eec3f..12491300bf7 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -84,7 +84,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/cache" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" clsessions "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/static" @@ -416,11 +415,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn testCtx := testutils.Context(t) // evm alway enabled for backward compatibility - telemetryManager := telemetry.NewManager(cfg.TelemetryIngress(), keyStore.CSA(), lggr) - initOps := []chainlink.CoreRelayerChainInitFunc{ - chainlink.InitDummy(testCtx, relayerFactory), - chainlink.InitEVM(testCtx, relayerFactory, evmOpts, telemetryManager), - } + initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitDummy(testCtx, relayerFactory), chainlink.InitEVM(testCtx, relayerFactory, evmOpts)} if cfg.CosmosEnabled() { cosmosCfg := chainlink.CosmosFactoryConfig{ @@ -468,7 +463,6 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn CapabilitiesRegistry: capabilitiesRegistry, CapabilitiesDispatcher: dispatcher, CapabilitiesPeerWrapper: peerWrapper, - TelemetryManager: telemetryManager, }) require.NoError(t, err) diff --git a/core/internal/mocks/head_reporter.go b/core/internal/mocks/head_reporter.go deleted file mode 100644 index 1a81b21bb13..00000000000 --- a/core/internal/mocks/head_reporter.go +++ /dev/null @@ -1,131 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - context "context" - - mock "github.com/stretchr/testify/mock" - - types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" -) - -// HeadReporter is an autogenerated mock type for the HeadReporter type -type HeadReporter struct { - mock.Mock -} - -type HeadReporter_Expecter struct { - mock *mock.Mock -} - -func (_m *HeadReporter) EXPECT() *HeadReporter_Expecter { - return &HeadReporter_Expecter{mock: &_m.Mock} -} - -// ReportNewHead provides a mock function with given fields: ctx, head -func (_m *HeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { - ret := _m.Called(ctx, head) - - if len(ret) == 0 { - panic("no return value specified for ReportNewHead") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok { - r0 = rf(ctx, head) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// HeadReporter_ReportNewHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportNewHead' -type HeadReporter_ReportNewHead_Call struct { - *mock.Call -} - -// ReportNewHead is a helper method to define mock.On call -// - ctx context.Context -// - head *types.Head -func (_e *HeadReporter_Expecter) ReportNewHead(ctx interface{}, head interface{}) *HeadReporter_ReportNewHead_Call { - return &HeadReporter_ReportNewHead_Call{Call: _e.mock.On("ReportNewHead", ctx, head)} -} - -func (_c *HeadReporter_ReportNewHead_Call) Run(run func(ctx context.Context, head *types.Head)) *HeadReporter_ReportNewHead_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*types.Head)) - }) - return _c -} - -func (_c *HeadReporter_ReportNewHead_Call) Return(_a0 error) *HeadReporter_ReportNewHead_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *HeadReporter_ReportNewHead_Call) RunAndReturn(run func(context.Context, *types.Head) error) *HeadReporter_ReportNewHead_Call { - _c.Call.Return(run) - return _c -} - -// ReportPeriodic provides a mock function with given fields: ctx -func (_m *HeadReporter) ReportPeriodic(ctx context.Context) error { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ReportPeriodic") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// HeadReporter_ReportPeriodic_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportPeriodic' -type HeadReporter_ReportPeriodic_Call struct { - *mock.Call -} - -// ReportPeriodic is a helper method to define mock.On call -// - ctx context.Context -func (_e *HeadReporter_Expecter) ReportPeriodic(ctx interface{}) *HeadReporter_ReportPeriodic_Call { - return &HeadReporter_ReportPeriodic_Call{Call: _e.mock.On("ReportPeriodic", ctx)} -} - -func (_c *HeadReporter_ReportPeriodic_Call) Run(run func(ctx context.Context)) *HeadReporter_ReportPeriodic_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *HeadReporter_ReportPeriodic_Call) Return(_a0 error) *HeadReporter_ReportPeriodic_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *HeadReporter_ReportPeriodic_Call) RunAndReturn(run func(context.Context) error) *HeadReporter_ReportPeriodic_Call { - _c.Call.Return(run) - return _c -} - -// NewHeadReporter creates a new instance of HeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewHeadReporter(t interface { - mock.TestingT - Cleanup(func()) -}) *HeadReporter { - mock := &HeadReporter{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/internal/mocks/prometheus_backend.go b/core/internal/mocks/prometheus_backend.go deleted file mode 100644 index d02f7062cbf..00000000000 --- a/core/internal/mocks/prometheus_backend.go +++ /dev/null @@ -1,204 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - big "math/big" - - mock "github.com/stretchr/testify/mock" -) - -// PrometheusBackend is an autogenerated mock type for the PrometheusBackend type -type PrometheusBackend struct { - mock.Mock -} - -type PrometheusBackend_Expecter struct { - mock *mock.Mock -} - -func (_m *PrometheusBackend) EXPECT() *PrometheusBackend_Expecter { - return &PrometheusBackend_Expecter{mock: &_m.Mock} -} - -// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge' -type PrometheusBackend_SetMaxUnconfirmedAge_Call struct { - *mock.Call -} - -// SetMaxUnconfirmedAge is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 float64 -func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - return &PrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(float64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Return(run) - return _c -} - -// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks' -type PrometheusBackend_SetMaxUnconfirmedBlocks_Call struct { - *mock.Call -} - -// SetMaxUnconfirmedBlocks is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 int64 -func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - return &PrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(int64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Return(run) - return _c -} - -// SetPipelineRunsQueued provides a mock function with given fields: n -func (_m *PrometheusBackend) SetPipelineRunsQueued(n int) { - _m.Called(n) -} - -// PrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued' -type PrometheusBackend_SetPipelineRunsQueued_Call struct { - *mock.Call -} - -// SetPipelineRunsQueued is a helper method to define mock.On call -// - n int -func (_e *PrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *PrometheusBackend_SetPipelineRunsQueued_Call { - return &PrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)} -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Return() *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Return(run) - return _c -} - -// SetPipelineTaskRunsQueued provides a mock function with given fields: n -func (_m *PrometheusBackend) SetPipelineTaskRunsQueued(n int) { - _m.Called(n) -} - -// PrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued' -type PrometheusBackend_SetPipelineTaskRunsQueued_Call struct { - *mock.Call -} - -// SetPipelineTaskRunsQueued is a helper method to define mock.On call -// - n int -func (_e *PrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - return &PrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)} -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Return(run) - return _c -} - -// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions' -type PrometheusBackend_SetUnconfirmedTransactions_Call struct { - *mock.Call -} - -// SetUnconfirmedTransactions is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 int64 -func (_e *PrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetUnconfirmedTransactions_Call { - return &PrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(int64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Return() *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Return(run) - return _c -} - -// NewPrometheusBackend creates a new instance of PrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewPrometheusBackend(t interface { - mock.TestingT - Cleanup(func()) -}) *PrometheusBackend { - mock := &PrometheusBackend{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 2885a3b56de..5df03752b46 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "net/http" + "slices" "sync" "github.com/ethereum/go-ethereum/common" @@ -23,6 +24,12 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/v2/core/capabilities" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" + "github.com/smartcontractkit/chainlink/v2/core/services/standardcapabilities" + "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/build" @@ -181,7 +188,6 @@ type ApplicationOpts struct { CapabilitiesRegistry *capabilities.Registry CapabilitiesDispatcher remotetypes.Dispatcher CapabilitiesPeerWrapper p2ptypes.PeerWrapper - TelemetryManager *telemetry.Manager } // NewApplication initializes a new store if one is not already @@ -292,7 +298,8 @@ func NewApplication(opts ApplicationOpts) (Application, error) { globalLogger.Info("Nurse service (automatic pprof profiling) is disabled") } - srvcs = append(srvcs, opts.TelemetryManager) + telemetryManager := telemetry.NewManager(cfg.TelemetryIngress(), keyStore.CSA(), globalLogger) + srvcs = append(srvcs, telemetryManager) backupCfg := cfg.Database().Backup() if backupCfg.Mode() != config.DatabaseBackupModeNone && backupCfg.Frequency() > 0 { @@ -361,7 +368,21 @@ func NewApplication(opts ApplicationOpts) (Application, error) { workflowORM = workflowstore.NewDBStore(opts.DS, globalLogger, clockwork.NewRealClock()) ) + promReporter := headreporter.NewPrometheusReporter(opts.DS, legacyEVMChains) + var headReporter *headreporter.HeadReporterService + if slices.ContainsFunc(legacyEVMChains.Slice(), func(chain legacyevm.Chain) bool { + return chain.Config().EVM().HeadTracker().HeadTelemetryEnabled() + }) { + telemReporter := headreporter.NewTelemetryReporter(legacyEVMChains, telemetryManager) + headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) + } else { + headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter) + } + for _, chain := range legacyEVMChains.Slice() { + if chain.Config().EVM().HeadTracker().HeadTelemetryEnabled() { + chain.HeadBroadcaster().Subscribe(headReporter) + } chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun) } @@ -426,7 +447,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { opts.DS, jobORM, opts.CapabilitiesRegistry, loopRegistrarConfig, - opts.TelemetryManager, + telemetryManager, pipelineRunner, opts.RelayerChainInteroperators), } @@ -475,7 +496,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { keyStore, pipelineRunner, peerWrapper, - opts.TelemetryManager, + telemetryManager, legacyEVMChains, globalLogger, cfg, @@ -498,7 +519,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { pipelineRunner, streamRegistry, peerWrapper, - opts.TelemetryManager, + telemetryManager, legacyEVMChains, globalLogger, ocr2DelegateConfig, diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 6c00213c971..63053c9bf64 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -7,11 +7,8 @@ import ( "sort" "sync" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/smartcontractkit/chainlink-common/pkg/loop" - relay "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" + "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters" @@ -116,7 +113,7 @@ func InitDummy(ctx context.Context, factory RelayerFactory) CoreRelayerChainInit } // InitEVM is a option for instantiating evm relayers -func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfig, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) CoreRelayerChainInitFunc { +func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfig) CoreRelayerChainInitFunc { return func(op *CoreRelayerChainInteroperators) (err error) { adapters, err2 := factory.NewEVM(ctx, config) if err2 != nil { @@ -130,8 +127,6 @@ func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfi legacyMap[id.ChainID] = a.Chain() } op.legacyChains.EVMChains = legacyevm.NewLegacyChains(legacyMap, config.AppConfig.EVMConfigs()) - headReporter := headreporter.NewHeadReporterService(config.DS, op.legacyChains.EVMChains, factory.Logger, monitoringEndpointGen) - op.srvs = append(op.srvs, headReporter) return nil } } diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go index 970ebbe78c6..883c6310466 100644 --- a/core/services/chainlink/relayer_chain_interoperators_test.go +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -218,7 +218,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { DS: db, }, CSAETHKeystore: keyStore, - }, nil), + }), }, expectedEVMChainCnt: 2, expectedEVMNodeCnt: 3, @@ -292,7 +292,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { DS: db, }, CSAETHKeystore: keyStore, - }, nil), + }), chainlink.InitStarknet(testctx, factory, chainlink.StarkNetFactoryConfig{ Keystore: keyStore.StarkNet(), TOMLConfigs: cfg.StarknetConfigs()}), diff --git a/core/services/relay/evm/headreporter/head_reporter.go b/core/services/relay/evm/headreporter/head_reporter.go index fe2ade6c199..e99888c8128 100644 --- a/core/services/relay/evm/headreporter/head_reporter.go +++ b/core/services/relay/evm/headreporter/head_reporter.go @@ -5,14 +5,12 @@ import ( "sync" "time" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -25,7 +23,6 @@ type ( HeadReporterService struct { services.StateMachine ds sqlutil.DataSource - chains legacyevm.LegacyChainContainer lggr logger.Logger newHeads *mailbox.Mailbox[*evmtypes.Head] chStop services.StopChan @@ -36,60 +33,24 @@ type ( } ) -func NewHeadReporterService(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, opts ...interface{}) *HeadReporterService { - reporters := make([]HeadReporter, 1, 2) - reporters[0] = NewPrometheusReporter(ds, chainContainer, lggr, opts) - telemetryEnabled := false - for _, chain := range chainContainer.Slice() { - if chain.Config().EVM().HeadTracker().HeadTelemetryEnabled() { - telemetryEnabled = true - break - } - } - if telemetryEnabled { - reporters = append(reporters, NewTelemetryReporter(chainContainer, monitoringEndpointGen)) - } - return NewHeadReporterServiceWithReporters(ds, chainContainer, lggr, reporters, opts) -} - -func NewHeadReporterServiceWithReporters(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, reporters []HeadReporter, opts ...interface{}) *HeadReporterService { - reportPeriod := 30 * time.Second - for _, opt := range opts { - switch v := opt.(type) { - case time.Duration: - reportPeriod = v - default: - lggr.Debugf("Unknown opt type '%T' passed to HeadReporterService", v) - } - } - chStop := make(chan struct{}) +func NewHeadReporterService(ds sqlutil.DataSource, lggr logger.Logger, reporters ...HeadReporter) *HeadReporterService { return &HeadReporterService{ - ds: ds, - chains: chainContainer, - lggr: lggr.Named("HeadReporterService"), - newHeads: mailbox.NewSingle[*evmtypes.Head](), - chStop: chStop, - wgDone: sync.WaitGroup{}, - reportPeriod: reportPeriod, - reporters: reporters, - unsubscribeFns: nil, + ds: ds, + lggr: lggr.Named("HeadReporter"), + newHeads: mailbox.NewSingle[*evmtypes.Head](), + chStop: make(chan struct{}), + reporters: reporters, } } -func (hrd *HeadReporterService) subscribe() { - hrd.unsubscribeFns = make([]func(), 0, hrd.chains.Len()) - for _, chain := range hrd.chains.Slice() { - if chain.Config().EVM().HeadTracker().HeadTelemetryEnabled() { - _, unsubscribe := chain.HeadBroadcaster().Subscribe(hrd) - hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe) - } - } +func (hrd *HeadReporterService) Subscribe(subFn func(types.HeadTrackable) (evmtypes.Head, func())) { + _, unsubscribe := subFn(hrd) + hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe) } func (hrd *HeadReporterService) Start(context.Context) error { return hrd.StartOnce(hrd.Name(), func() error { hrd.wgDone.Add(1) - hrd.subscribe() go hrd.eventLoop() return nil }) diff --git a/core/services/relay/evm/headreporter/head_reporter_test.go b/core/services/relay/evm/headreporter/head_reporter_test.go index 0e437625f06..ded7e1fb61b 100644 --- a/core/services/relay/evm/headreporter/head_reporter_test.go +++ b/core/services/relay/evm/headreporter/head_reporter_test.go @@ -1,85 +1,37 @@ -package headreporter_test +package headreporter import ( "sync/atomic" "testing" "time" - "github.com/jmoiron/sqlx" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" - "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" ) -func newHead() evmtypes.Head { +func NewHead() evmtypes.Head { return evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(0)} } -func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { - config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) - keyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) - require.NoError(t, err) - lggr := logger.TestLogger(t) - lpOpts := logpoller.Opts{ - PollPeriod: 100 * time.Millisecond, - FinalityDepth: 2, - BackfillBatchSize: 3, - RpcBatchSize: 2, - KeepFinalizedBlocksDepth: 1000, - } - ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts) - - txm, err := txmgr.NewTxm( - db, - evmConfig, - evmConfig.GasEstimator(), - evmConfig.Transactions(), - nil, - dbConfig, - dbConfig.Listener(), - ethClient, - lggr, - lp, - keyStore, - estimator, - ht) - require.NoError(t, err) - - cfg := configtest.NewGeneralConfig(t, nil) - return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) -} - func Test_HeadReporterService(t *testing.T) { t.Run("report everything", func(t *testing.T) { db := pgtest.NewSqlxDB(t) - headReporter := mocks.NewHeadReporter(t) - service := headreporter.NewHeadReporterServiceWithReporters(db, newLegacyChainContainer(t, db), logger.TestLogger(t), []headreporter.HeadReporter{headReporter}, time.Second) + headReporter := NewMockHeadReporter(t) + service := NewHeadReporterService(db, logger.TestLogger(t), headReporter) + service.reportPeriod = time.Second err := service.Start(testutils.Context(t)) require.NoError(t, err) var reportCalls atomic.Int32 - head := newHead() + head := NewHead() headReporter.On("ReportNewHead", mock.Anything, &head).Run(func(args mock.Arguments) { reportCalls.Add(1) }).Return(nil) diff --git a/core/services/relay/evm/headreporter/helper_test.go b/core/services/relay/evm/headreporter/helper_test.go new file mode 100644 index 00000000000..fa05182a851 --- /dev/null +++ b/core/services/relay/evm/headreporter/helper_test.go @@ -0,0 +1,5 @@ +package headreporter + +func (p *prometheusReporter) SetBackend(b PrometheusBackend) { + p.backend = b +} diff --git a/core/services/relay/evm/headreporter/mock_head_reporter_test.go b/core/services/relay/evm/headreporter/mock_head_reporter_test.go new file mode 100644 index 00000000000..21978abb86a --- /dev/null +++ b/core/services/relay/evm/headreporter/mock_head_reporter_test.go @@ -0,0 +1,130 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package headreporter + +import ( + context "context" + + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + mock "github.com/stretchr/testify/mock" +) + +// MockHeadReporter is an autogenerated mock type for the HeadReporter type +type MockHeadReporter struct { + mock.Mock +} + +type MockHeadReporter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockHeadReporter) EXPECT() *MockHeadReporter_Expecter { + return &MockHeadReporter_Expecter{mock: &_m.Mock} +} + +// ReportNewHead provides a mock function with given fields: ctx, head +func (_m *MockHeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { + ret := _m.Called(ctx, head) + + if len(ret) == 0 { + panic("no return value specified for ReportNewHead") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok { + r0 = rf(ctx, head) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockHeadReporter_ReportNewHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportNewHead' +type MockHeadReporter_ReportNewHead_Call struct { + *mock.Call +} + +// ReportNewHead is a helper method to define mock.On call +// - ctx context.Context +// - head *types.Head +func (_e *MockHeadReporter_Expecter) ReportNewHead(ctx interface{}, head interface{}) *MockHeadReporter_ReportNewHead_Call { + return &MockHeadReporter_ReportNewHead_Call{Call: _e.mock.On("ReportNewHead", ctx, head)} +} + +func (_c *MockHeadReporter_ReportNewHead_Call) Run(run func(ctx context.Context, head *types.Head)) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*types.Head)) + }) + return _c +} + +func (_c *MockHeadReporter_ReportNewHead_Call) Return(_a0 error) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockHeadReporter_ReportNewHead_Call) RunAndReturn(run func(context.Context, *types.Head) error) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Return(run) + return _c +} + +// ReportPeriodic provides a mock function with given fields: ctx +func (_m *MockHeadReporter) ReportPeriodic(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ReportPeriodic") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockHeadReporter_ReportPeriodic_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportPeriodic' +type MockHeadReporter_ReportPeriodic_Call struct { + *mock.Call +} + +// ReportPeriodic is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockHeadReporter_Expecter) ReportPeriodic(ctx interface{}) *MockHeadReporter_ReportPeriodic_Call { + return &MockHeadReporter_ReportPeriodic_Call{Call: _e.mock.On("ReportPeriodic", ctx)} +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) Run(run func(ctx context.Context)) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) Return(_a0 error) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) RunAndReturn(run func(context.Context) error) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Return(run) + return _c +} + +// NewMockHeadReporter creates a new instance of MockHeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockHeadReporter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockHeadReporter { + mock := &MockHeadReporter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/relay/evm/headreporter/mock_prometheus_backend_test.go b/core/services/relay/evm/headreporter/mock_prometheus_backend_test.go new file mode 100644 index 00000000000..ca83f6c4fbb --- /dev/null +++ b/core/services/relay/evm/headreporter/mock_prometheus_backend_test.go @@ -0,0 +1,204 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package headreporter + +import ( + big "math/big" + + mock "github.com/stretchr/testify/mock" +) + +// MockPrometheusBackend is an autogenerated mock type for the PrometheusBackend type +type MockPrometheusBackend struct { + mock.Mock +} + +type MockPrometheusBackend_Expecter struct { + mock *mock.Mock +} + +func (_m *MockPrometheusBackend) EXPECT() *MockPrometheusBackend_Expecter { + return &MockPrometheusBackend_Expecter{mock: &_m.Mock} +} + +// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge' +type MockPrometheusBackend_SetMaxUnconfirmedAge_Call struct { + *mock.Call +} + +// SetMaxUnconfirmedAge is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 float64 +func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + return &MockPrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(float64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Return(run) + return _c +} + +// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks' +type MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call struct { + *mock.Call +} + +// SetMaxUnconfirmedBlocks is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 int64 +func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + return &MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Return(run) + return _c +} + +// SetPipelineRunsQueued provides a mock function with given fields: n +func (_m *MockPrometheusBackend) SetPipelineRunsQueued(n int) { + _m.Called(n) +} + +// MockPrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued' +type MockPrometheusBackend_SetPipelineRunsQueued_Call struct { + *mock.Call +} + +// SetPipelineRunsQueued is a helper method to define mock.On call +// - n int +func (_e *MockPrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + return &MockPrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)} +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Return(run) + return _c +} + +// SetPipelineTaskRunsQueued provides a mock function with given fields: n +func (_m *MockPrometheusBackend) SetPipelineTaskRunsQueued(n int) { + _m.Called(n) +} + +// MockPrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued' +type MockPrometheusBackend_SetPipelineTaskRunsQueued_Call struct { + *mock.Call +} + +// SetPipelineTaskRunsQueued is a helper method to define mock.On call +// - n int +func (_e *MockPrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + return &MockPrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)} +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Return(run) + return _c +} + +// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions' +type MockPrometheusBackend_SetUnconfirmedTransactions_Call struct { + *mock.Call +} + +// SetUnconfirmedTransactions is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 int64 +func (_e *MockPrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + return &MockPrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Return() *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Return(run) + return _c +} + +// NewMockPrometheusBackend creates a new instance of MockPrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockPrometheusBackend(t interface { + mock.TestingT + Cleanup(func()) +}) *MockPrometheusBackend { + mock := &MockPrometheusBackend{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/relay/evm/headreporter/prometheus_reporter.go b/core/services/relay/evm/headreporter/prometheus_reporter.go index 5d8cf42bc49..3e39c7aca45 100644 --- a/core/services/relay/evm/headreporter/prometheus_reporter.go +++ b/core/services/relay/evm/headreporter/prometheus_reporter.go @@ -16,7 +16,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) type ( @@ -60,20 +59,11 @@ var ( }) ) -func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) HeadReporter { - var backend PrometheusBackend = defaultBackend{} - for _, opt := range opts { - switch v := opt.(type) { - case PrometheusBackend: - backend = v - default: - lggr.Debugf("Unknown opt type '%T' passed to PrometheusReporter", v) - } - } +func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer) *prometheusReporter { return &prometheusReporter{ ds: ds, chains: chainContainer, - backend: backend, + backend: defaultBackend{}, } } diff --git a/core/services/relay/evm/headreporter/prometheus_reporter_test.go b/core/services/relay/evm/headreporter/prometheus_reporter_test.go index 7e9240ab95b..092b67fd997 100644 --- a/core/services/relay/evm/headreporter/prometheus_reporter_test.go +++ b/core/services/relay/evm/headreporter/prometheus_reporter_test.go @@ -3,32 +3,39 @@ package headreporter_test import ( "math/big" "testing" + "time" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" - - "github.com/smartcontractkit/chainlink/v2/core/logger" - + "github.com/jmoiron/sqlx" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" ) func Test_PrometheusReporter(t *testing.T) { t.Run("with nothing in the database", func(t *testing.T) { db := pgtest.NewSqlxDB(t) - backend := mocks.NewPrometheusBackend(t) - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) + backend := headreporter.NewMockPrometheusBackend(t) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - head := newHead() + head := headreporter.NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -49,16 +56,17 @@ func Test_PrometheusReporter(t *testing.T) { cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7)) - backend := mocks.NewPrometheusBackend(t) + backend := headreporter.NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(3)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), mock.MatchedBy(func(s float64) bool { return s > 0 })).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(35)).Return() - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) - head := newHead() + head := headreporter.NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -77,14 +85,15 @@ func Test_PrometheusReporter(t *testing.T) { cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 2) - backend := mocks.NewPrometheusBackend(t) + backend := headreporter.NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) - head := newHead() + head := headreporter.NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -95,3 +104,39 @@ func Test_PrometheusReporter(t *testing.T) { require.NoError(t, err) }) } + +func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { + config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) + keyStore := cltest.NewKeyStore(t, db).Eth() + ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) + require.NoError(t, err) + lggr := logger.TestLogger(t) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts) + + txm, err := txmgr.NewTxm( + db, + evmConfig, + evmConfig.GasEstimator(), + evmConfig.Transactions(), + nil, + dbConfig, + dbConfig.Listener(), + ethClient, + lggr, + lp, + keyStore, + estimator) + require.NoError(t, err) + + cfg := configtest.NewGeneralConfig(t, nil) + return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) +} From 7cbf69ccf6ce5bb9c1c89a400b437e22e413d3ac Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Tue, 6 Aug 2024 15:24:58 +0100 Subject: [PATCH 07/21] review --- common/headtracker/types/config.go | 2 +- .../evm/config/chain_scoped_head_tracker.go | 4 +- core/chains/evm/config/config.go | 2 +- core/chains/evm/config/toml/config.go | 6 +- .../evm/config/toml/defaults/fallback.toml | 2 +- .../chains/evm/headtracker/head_saver_test.go | 2 +- core/config/docs/chains-evm.toml | 4 +- core/services/chainlink/application.go | 4 +- core/services/chainlink/config_test.go | 4 +- .../chainlink/testdata/config-full.toml | 2 +- .../config-multi-chain-effective.toml | 6 +- core/web/resolver/testdata/config-full.toml | 2 +- .../config-multi-chain-effective.toml | 6 +- docs/CONFIG.md | 126 +++++++++--------- .../disk-based-logging-disabled.txtar | 2 +- .../validate/disk-based-logging-no-dir.txtar | 2 +- .../node/validate/disk-based-logging.txtar | 2 +- testdata/scripts/node/validate/invalid.txtar | 2 +- testdata/scripts/node/validate/valid.txtar | 2 +- 19 files changed, 91 insertions(+), 91 deletions(-) diff --git a/common/headtracker/types/config.go b/common/headtracker/types/config.go index 289d2bc502c..5d1c2f3bd9c 100644 --- a/common/headtracker/types/config.go +++ b/common/headtracker/types/config.go @@ -15,5 +15,5 @@ type HeadTrackerConfig interface { SamplingInterval() time.Duration FinalityTagBypass() bool MaxAllowedFinalityDepth() uint32 - HeadTelemetryEnabled() bool + TelemetryEnabled() bool } diff --git a/core/chains/evm/config/chain_scoped_head_tracker.go b/core/chains/evm/config/chain_scoped_head_tracker.go index de6e19e9d6e..4132a31ff0d 100644 --- a/core/chains/evm/config/chain_scoped_head_tracker.go +++ b/core/chains/evm/config/chain_scoped_head_tracker.go @@ -30,6 +30,6 @@ func (h *headTrackerConfig) MaxAllowedFinalityDepth() uint32 { return *h.c.MaxAllowedFinalityDepth } -func (h *headTrackerConfig) HeadTelemetryEnabled() bool { - return *h.c.HeadTelemetryEnabled +func (h *headTrackerConfig) TelemetryEnabled() bool { + return *h.c.TelemetryEnabled } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index e6265c40f55..5a9c9f322ea 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -75,7 +75,7 @@ type HeadTracker interface { SamplingInterval() time.Duration FinalityTagBypass() bool MaxAllowedFinalityDepth() uint32 - HeadTelemetryEnabled() bool + TelemetryEnabled() bool } type BalanceMonitor interface { diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 7f7dc0c1939..2d516831d30 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -748,7 +748,7 @@ type HeadTracker struct { SamplingInterval *commonconfig.Duration MaxAllowedFinalityDepth *uint32 FinalityTagBypass *bool - HeadTelemetryEnabled *bool + TelemetryEnabled *bool } func (t *HeadTracker) setFrom(f *HeadTracker) { @@ -767,8 +767,8 @@ func (t *HeadTracker) setFrom(f *HeadTracker) { if v := f.FinalityTagBypass; v != nil { t.FinalityTagBypass = v } - if v := f.HeadTelemetryEnabled; v != nil { - t.HeadTelemetryEnabled = v + if v := f.TelemetryEnabled; v != nil { + t.TelemetryEnabled = v } } diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index 2e26c9466a2..8c169795f8e 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -61,7 +61,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' FinalityTagBypass = true MaxAllowedFinalityDepth = 10000 -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 diff --git a/core/chains/evm/headtracker/head_saver_test.go b/core/chains/evm/headtracker/head_saver_test.go index c87e1830d91..fe64f108b05 100644 --- a/core/chains/evm/headtracker/head_saver_test.go +++ b/core/chains/evm/headtracker/head_saver_test.go @@ -42,7 +42,7 @@ func (h *headTrackerConfig) FinalityTagBypass() bool { func (h *headTrackerConfig) MaxAllowedFinalityDepth() uint32 { return 10000 } -func (h *headTrackerConfig) HeadTelemetryEnabled() bool { +func (h *headTrackerConfig) TelemetryEnabled() bool { return false } diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index c29c0ce04ed..06e98f9e203 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -334,8 +334,8 @@ FinalityTagBypass = true # Default # If actual finality depth exceeds this number, HeadTracker aborts backfill and returns an error. # Has no effect if `FinalityTagsEnabled` = false MaxAllowedFinalityDepth = 10000 # Default -# HeadTelemetryEnabled controls if it collects information about new blocks from blockchain -HeadTelemetryEnabled = false # Default +# TelemetryEnabled controls if it collects information about new blocks from blockchain +TelemetryEnabled = false # Default [[EVM.KeySpecific]] # Key is the account to apply these settings to diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 5df03752b46..d305bc1e9cb 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -371,7 +371,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { promReporter := headreporter.NewPrometheusReporter(opts.DS, legacyEVMChains) var headReporter *headreporter.HeadReporterService if slices.ContainsFunc(legacyEVMChains.Slice(), func(chain legacyevm.Chain) bool { - return chain.Config().EVM().HeadTracker().HeadTelemetryEnabled() + return chain.Config().EVM().HeadTracker().TelemetryEnabled() }) { telemReporter := headreporter.NewTelemetryReporter(legacyEVMChains, telemetryManager) headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) @@ -380,7 +380,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { } for _, chain := range legacyEVMChains.Slice() { - if chain.Config().EVM().HeadTracker().HeadTelemetryEnabled() { + if chain.Config().EVM().HeadTracker().TelemetryEnabled() { chain.HeadBroadcaster().Subscribe(headReporter) } chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun) diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 2d6794ece7e..40d62c1b921 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -587,7 +587,7 @@ func TestConfig_Marshal(t *testing.T) { SamplingInterval: &hour, FinalityTagBypass: ptr[bool](false), MaxAllowedFinalityDepth: ptr[uint32](1500), - HeadTelemetryEnabled: ptr[bool](true), + TelemetryEnabled: ptr[bool](true), }, NodePool: evmcfg.NodePool{ @@ -1055,7 +1055,7 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 1500 FinalityTagBypass = false -HeadTelemetryEnabled = true +TelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 40ecf8060d3..6543cf08b67 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -347,7 +347,7 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 1500 FinalityTagBypass = false -HeadTelemetryEnabled = true +TelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 81e6fa0dcea..39f579f9fd7 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -324,7 +324,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -425,7 +425,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -520,7 +520,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 62dfb47d7e0..1ec0302e0ae 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -346,7 +346,7 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = true +TelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 8059832ff6f..ad7dcd6c160 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -324,7 +324,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -425,7 +425,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -520,7 +520,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index bcf7267e937..cda4019bb36 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1839,7 +1839,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -1934,7 +1934,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2029,7 +2029,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2124,7 +2124,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2220,7 +2220,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2315,7 +2315,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2410,7 +2410,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2506,7 +2506,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2601,7 +2601,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2695,7 +2695,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2789,7 +2789,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2884,7 +2884,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2980,7 +2980,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3075,7 +3075,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3170,7 +3170,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3265,7 +3265,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3360,7 +3360,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3455,7 +3455,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3550,7 +3550,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3645,7 +3645,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3740,7 +3740,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3835,7 +3835,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3931,7 +3931,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4026,7 +4026,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4120,7 +4120,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4215,7 +4215,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4310,7 +4310,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4405,7 +4405,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4500,7 +4500,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4594,7 +4594,7 @@ MaxBufferSize = 100 SamplingInterval = '0s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4689,7 +4689,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4784,7 +4784,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4879,7 +4879,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4974,7 +4974,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5068,7 +5068,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5163,7 +5163,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5258,7 +5258,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5544,7 +5544,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5639,7 +5639,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5734,7 +5734,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5829,7 +5829,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5924,7 +5924,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6018,7 +6018,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6112,7 +6112,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6206,7 +6206,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6301,7 +6301,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6396,7 +6396,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6490,7 +6490,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6585,7 +6585,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6680,7 +6680,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6776,7 +6776,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6872,7 +6872,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6967,7 +6967,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7062,7 +7062,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7157,7 +7157,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7252,7 +7252,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7347,7 +7347,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7442,7 +7442,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7537,7 +7537,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -8193,7 +8193,7 @@ MaxBufferSize = 3 # Default SamplingInterval = '1s' # Default FinalityTagBypass = true # Default MaxAllowedFinalityDepth = 10000 # Default -HeadTelemetryEnabled = false # Default +TelemetryEnabled = false # Default ``` The head tracker continually listens for new heads from the chain. @@ -8240,11 +8240,11 @@ MaxAllowedFinalityDepth - defines maximum number of blocks between the most rece If actual finality depth exceeds this number, HeadTracker aborts backfill and returns an error. Has no effect if `FinalityTagsEnabled` = false -### HeadTelemetryEnabled +### TelemetryEnabled ```toml -HeadTelemetryEnabled = false # Default +TelemetryEnabled = false # Default ``` -HeadTelemetryEnabled controls if it collects information about new blocks from blockchain +TelemetryEnabled controls if it collects information about new blocks from blockchain ## EVM.KeySpecific ```toml diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 9172986830b..d444abaa38e 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -380,7 +380,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 98b97fd98df..094bd418e9c 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -380,7 +380,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index bcca7c4b453..4844a48b8c6 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -380,7 +380,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index b93a7454887..d37dade3064 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -370,7 +370,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index eb37b63342b..8134c5473fb 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -377,7 +377,7 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -HeadTelemetryEnabled = false +TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 From d807c077a4ed81696b92a69feadf816b4026616e Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Tue, 6 Aug 2024 18:36:16 +0100 Subject: [PATCH 08/21] Revert moving to relayer --- .mockery.yaml | 19 +- common/headtracker/types/config.go | 1 - .../evm/config/chain_scoped_head_tracker.go | 4 - core/chains/evm/config/config.go | 1 - core/chains/evm/config/toml/config.go | 4 - .../evm/config/toml/defaults/fallback.toml | 1 - .../chains/evm/headtracker/head_saver_test.go | 3 - core/cmd/shell.go | 1 - core/config/app_config.go | 1 + core/config/docs/chains-evm.toml | 2 - core/config/docs/core.toml | 4 + core/config/head_report_config.go | 5 + core/config/toml/types.go | 12 ++ core/internal/cltest/mocks.go | 7 +- core/internal/mocks/head_reporter.go | 66 ++++++ .../mocks/monitoring_endpoint_generator.go | 88 -------- core/internal/mocks/prometheus_backend.go | 204 ++++++++++++++++++ core/services/chainlink/application.go | 21 +- core/services/chainlink/config_general.go | 6 + .../services/chainlink/config_general_test.go | 1 + core/services/chainlink/config_head_report.go | 13 ++ .../chainlink/config_head_report_test.go | 18 ++ core/services/chainlink/config_test.go | 8 +- .../chainlink/mocks/general_config.go | 20 ++ .../chainlink/relayer_chain_interoperators.go | 3 +- .../relayer_chain_interoperators_test.go | 9 +- .../testdata/config-empty-effective.toml | 3 + .../chainlink/testdata/config-full.toml | 4 +- .../config-multi-chain-effective.toml | 6 +- .../evm => }/headreporter/head_reporter.go | 61 ++++-- .../headreporter/head_reporter_test.go | 93 ++++++++ .../headreporter/prometheus_reporter.go | 14 +- .../headreporter/prometheus_reporter_test.go | 72 ++----- .../headreporter/telemetry_reporter.go | 3 +- .../headreporter/telemetry_reporter_test.go | 11 +- .../evm/headreporter/head_reporter_test.go | 45 ---- .../relay/evm/headreporter/helper_test.go | 5 - .../headreporter/mock_head_reporter_test.go | 130 ----------- .../mock_prometheus_backend_test.go | 204 ------------------ core/services/telemetry/common.go | 1 + .../mocks/monitoring_endpoint_generator.go | 49 +++++ .../testdata/config-empty-effective.toml | 3 + core/web/resolver/testdata/config-full.toml | 4 +- .../config-multi-chain-effective.toml | 6 +- docs/CONFIG.md | 79 ++----- testdata/scripts/node/validate/default.txtar | 3 + .../disk-based-logging-disabled.txtar | 4 +- .../validate/disk-based-logging-no-dir.txtar | 4 +- .../node/validate/disk-based-logging.txtar | 4 +- .../node/validate/invalid-ocr-p2p.txtar | 3 + testdata/scripts/node/validate/invalid.txtar | 4 +- testdata/scripts/node/validate/valid.txtar | 4 +- testdata/scripts/node/validate/warnings.txtar | 3 + 53 files changed, 644 insertions(+), 700 deletions(-) create mode 100644 core/config/head_report_config.go create mode 100644 core/internal/mocks/head_reporter.go delete mode 100644 core/internal/mocks/monitoring_endpoint_generator.go create mode 100644 core/internal/mocks/prometheus_backend.go create mode 100644 core/services/chainlink/config_head_report.go create mode 100644 core/services/chainlink/config_head_report_test.go rename core/services/{relay/evm => }/headreporter/head_reporter.go (52%) create mode 100644 core/services/headreporter/head_reporter_test.go rename core/services/{relay/evm => }/headreporter/prometheus_reporter.go (94%) rename core/services/{relay/evm => }/headreporter/prometheus_reporter_test.go (59%) rename core/services/{relay/evm => }/headreporter/telemetry_reporter.go (93%) rename core/services/{relay/evm => }/headreporter/telemetry_reporter_test.go (88%) delete mode 100644 core/services/relay/evm/headreporter/head_reporter_test.go delete mode 100644 core/services/relay/evm/headreporter/helper_test.go delete mode 100644 core/services/relay/evm/headreporter/mock_head_reporter_test.go delete mode 100644 core/services/relay/evm/headreporter/mock_prometheus_backend_test.go create mode 100644 core/services/telemetry/mocks/monitoring_endpoint_generator.go diff --git a/.mockery.yaml b/.mockery.yaml index 59174bacb5b..abb3105b136 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -262,6 +262,11 @@ packages: ORM: Runner: PipelineParamUnmarshaler: + github.com/smartcontractkit/chainlink/v2/core/services/promreporter: + config: + dir: core/internal/mocks + interfaces: + PrometheusBackend: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm: interfaces: BatchCaller: @@ -278,15 +283,6 @@ packages: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types: interfaces: LogPollerWrapper: - github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter: - config: - dir: "{{ .InterfaceDir }}" - filename: "mock_{{ .InterfaceName | snakecase }}_test.go" - inpackage: true - mockname: "Mock{{ .InterfaceName | camelcase }}" - interfaces: - HeadReporter: - PrometheusBackend: github.com/smartcontractkit/chainlink/v2/core/services/s4: interfaces: ORM: @@ -305,11 +301,6 @@ packages: interfaces: Config: FeeConfig: - github.com/smartcontractkit/chainlink/v2/core/services/telemetry: - config: - dir: "{{ .InterfaceDir }}/../../internal/mocks" - interfaces: - MonitoringEndpointGenerator: github.com/smartcontractkit/chainlink/v2/core/services/webhook: interfaces: ExternalInitiatorManager: diff --git a/common/headtracker/types/config.go b/common/headtracker/types/config.go index 5d1c2f3bd9c..06ad93d39d2 100644 --- a/common/headtracker/types/config.go +++ b/common/headtracker/types/config.go @@ -15,5 +15,4 @@ type HeadTrackerConfig interface { SamplingInterval() time.Duration FinalityTagBypass() bool MaxAllowedFinalityDepth() uint32 - TelemetryEnabled() bool } diff --git a/core/chains/evm/config/chain_scoped_head_tracker.go b/core/chains/evm/config/chain_scoped_head_tracker.go index 4132a31ff0d..8bc1ff188a7 100644 --- a/core/chains/evm/config/chain_scoped_head_tracker.go +++ b/core/chains/evm/config/chain_scoped_head_tracker.go @@ -29,7 +29,3 @@ func (h *headTrackerConfig) FinalityTagBypass() bool { func (h *headTrackerConfig) MaxAllowedFinalityDepth() uint32 { return *h.c.MaxAllowedFinalityDepth } - -func (h *headTrackerConfig) TelemetryEnabled() bool { - return *h.c.TelemetryEnabled -} diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 5a9c9f322ea..3ccdfeea8b8 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -75,7 +75,6 @@ type HeadTracker interface { SamplingInterval() time.Duration FinalityTagBypass() bool MaxAllowedFinalityDepth() uint32 - TelemetryEnabled() bool } type BalanceMonitor interface { diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 2d516831d30..2cb29d97696 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -748,7 +748,6 @@ type HeadTracker struct { SamplingInterval *commonconfig.Duration MaxAllowedFinalityDepth *uint32 FinalityTagBypass *bool - TelemetryEnabled *bool } func (t *HeadTracker) setFrom(f *HeadTracker) { @@ -767,9 +766,6 @@ func (t *HeadTracker) setFrom(f *HeadTracker) { if v := f.FinalityTagBypass; v != nil { t.FinalityTagBypass = v } - if v := f.TelemetryEnabled; v != nil { - t.TelemetryEnabled = v - } } func (t *HeadTracker) ValidateConfig() (err error) { diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index 8c169795f8e..a47e56bc918 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -61,7 +61,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' FinalityTagBypass = true MaxAllowedFinalityDepth = 10000 -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 diff --git a/core/chains/evm/headtracker/head_saver_test.go b/core/chains/evm/headtracker/head_saver_test.go index fe64f108b05..43e79235e90 100644 --- a/core/chains/evm/headtracker/head_saver_test.go +++ b/core/chains/evm/headtracker/head_saver_test.go @@ -42,9 +42,6 @@ func (h *headTrackerConfig) FinalityTagBypass() bool { func (h *headTrackerConfig) MaxAllowedFinalityDepth() uint32 { return 10000 } -func (h *headTrackerConfig) TelemetryEnabled() bool { - return false -} type config struct { finalityDepth uint32 diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 3fb5cc5e9a8..3d055bb03a9 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -182,7 +182,6 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G ChainOpts: legacyevm.ChainOpts{AppConfig: cfg, MailMon: mailMon, DS: ds}, MercuryTransmitter: cfg.Mercury().Transmitter(), } - // evm always enabled for backward compatibility // TODO BCF-2510 this needs to change in order to clear the path for EVM extraction initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitDummy(ctx, relayerFactory), chainlink.InitEVM(ctx, relayerFactory, evmFactoryCfg)} diff --git a/core/config/app_config.go b/core/config/app_config.go index 112e242636f..fe877d110ab 100644 --- a/core/config/app_config.go +++ b/core/config/app_config.go @@ -53,6 +53,7 @@ type AppConfig interface { Pyroscope() Pyroscope Sentry() Sentry TelemetryIngress() TelemetryIngress + HeadReport() HeadReport Threshold() Threshold WebServer() WebServer Tracing() Tracing diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 06e98f9e203..444804b3826 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -334,8 +334,6 @@ FinalityTagBypass = true # Default # If actual finality depth exceeds this number, HeadTracker aborts backfill and returns an error. # Has no effect if `FinalityTagsEnabled` = false MaxAllowedFinalityDepth = 10000 # Default -# TelemetryEnabled controls if it collects information about new blocks from blockchain -TelemetryEnabled = false # Default [[EVM.KeySpecific]] # Key is the account to apply these settings to diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index d0960779c6c..e45a7cd3841 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -651,3 +651,7 @@ TransmitQueueMaxSize = 10_000 # Default # when sending a message to the mercury server, before aborting and considering # the transmission to be failed. TransmitTimeout = "5s" # Default + +[HeadReport] +# TelemetryEnabled controls if it collects information about new blocks from blockchain +TelemetryEnabled = false # Default diff --git a/core/config/head_report_config.go b/core/config/head_report_config.go new file mode 100644 index 00000000000..9f4ae85eb6c --- /dev/null +++ b/core/config/head_report_config.go @@ -0,0 +1,5 @@ +package config + +type HeadReport interface { + TelemetryEnabled() bool +} diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 0c91ddd81a9..a503720ea9e 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -56,6 +56,7 @@ type Core struct { Insecure Insecure `toml:",omitempty"` Tracing Tracing `toml:",omitempty"` Mercury Mercury `toml:",omitempty"` + HeadReport HeadReport `toml:",omitempty"` Capabilities Capabilities `toml:",omitempty"` } @@ -76,6 +77,7 @@ func (c *Core) SetFrom(f *Core) { c.TelemetryIngress.setFrom(&f.TelemetryIngress) c.AuditLogger.SetFrom(&f.AuditLogger) c.Log.setFrom(&f.Log) + c.HeadReport.setFrom(&f.HeadReport) c.WebServer.setFrom(&f.WebServer) c.JobPipeline.setFrom(&f.JobPipeline) @@ -485,6 +487,16 @@ func (t *TelemetryIngress) setFrom(f *TelemetryIngress) { } } +type HeadReport struct { + TelemetryEnabled *bool +} + +func (t *HeadReport) setFrom(f *HeadReport) { + if v := f.TelemetryEnabled; v != nil { + t.TelemetryEnabled = v + } +} + type AuditLogger struct { Enabled *bool ForwardToUrl *commonconfig.URL diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index 25273380272..fd01f72c131 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -10,16 +10,16 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/jmoiron/sqlx" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" "github.com/smartcontractkit/chainlink/v2/core/cmd" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -405,7 +405,6 @@ func NewLegacyChainsWithMockChainAndTxManager(t testing.TB, ethClient evmclient. ch.On("ID").Return(scopedCfg.EVM().ChainID()) ch.On("Config").Return(scopedCfg) ch.On("TxManager").Return(txm) - ch.On("HeadBroadcaster").Return(headtracker.NewHeadBroadcaster(ch.Logger())) return NewLegacyChainsWithChain(ch, cfg) } diff --git a/core/internal/mocks/head_reporter.go b/core/internal/mocks/head_reporter.go new file mode 100644 index 00000000000..49e4e7f491d --- /dev/null +++ b/core/internal/mocks/head_reporter.go @@ -0,0 +1,66 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" +) + +// HeadReporter is an autogenerated mock type for the HeadReporter type +type HeadReporter struct { + mock.Mock +} + +// ReportNewHead provides a mock function with given fields: ctx, head +func (_m *HeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { + ret := _m.Called(ctx, head) + + if len(ret) == 0 { + panic("no return value specified for ReportNewHead") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok { + r0 = rf(ctx, head) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ReportPeriodic provides a mock function with given fields: ctx +func (_m *HeadReporter) ReportPeriodic(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ReportPeriodic") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewHeadReporter creates a new instance of HeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewHeadReporter(t interface { + mock.TestingT + Cleanup(func()) +}) *HeadReporter { + mock := &HeadReporter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/internal/mocks/monitoring_endpoint_generator.go b/core/internal/mocks/monitoring_endpoint_generator.go deleted file mode 100644 index 1384e2e2a43..00000000000 --- a/core/internal/mocks/monitoring_endpoint_generator.go +++ /dev/null @@ -1,88 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - commontypes "github.com/smartcontractkit/libocr/commontypes" - mock "github.com/stretchr/testify/mock" - - synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" -) - -// MonitoringEndpointGenerator is an autogenerated mock type for the MonitoringEndpointGenerator type -type MonitoringEndpointGenerator struct { - mock.Mock -} - -type MonitoringEndpointGenerator_Expecter struct { - mock *mock.Mock -} - -func (_m *MonitoringEndpointGenerator) EXPECT() *MonitoringEndpointGenerator_Expecter { - return &MonitoringEndpointGenerator_Expecter{mock: &_m.Mock} -} - -// GenMonitoringEndpoint provides a mock function with given fields: network, chainID, contractID, telemType -func (_m *MonitoringEndpointGenerator) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { - ret := _m.Called(network, chainID, contractID, telemType) - - if len(ret) == 0 { - panic("no return value specified for GenMonitoringEndpoint") - } - - var r0 commontypes.MonitoringEndpoint - if rf, ok := ret.Get(0).(func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint); ok { - r0 = rf(network, chainID, contractID, telemType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(commontypes.MonitoringEndpoint) - } - } - - return r0 -} - -// MonitoringEndpointGenerator_GenMonitoringEndpoint_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenMonitoringEndpoint' -type MonitoringEndpointGenerator_GenMonitoringEndpoint_Call struct { - *mock.Call -} - -// GenMonitoringEndpoint is a helper method to define mock.On call -// - network string -// - chainID string -// - contractID string -// - telemType synchronization.TelemetryType -func (_e *MonitoringEndpointGenerator_Expecter) GenMonitoringEndpoint(network interface{}, chainID interface{}, contractID interface{}, telemType interface{}) *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call { - return &MonitoringEndpointGenerator_GenMonitoringEndpoint_Call{Call: _e.mock.On("GenMonitoringEndpoint", network, chainID, contractID, telemType)} -} - -func (_c *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call) Run(run func(network string, chainID string, contractID string, telemType synchronization.TelemetryType)) *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string), args[3].(synchronization.TelemetryType)) - }) - return _c -} - -func (_c *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call) Return(_a0 commontypes.MonitoringEndpoint) *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call) RunAndReturn(run func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint) *MonitoringEndpointGenerator_GenMonitoringEndpoint_Call { - _c.Call.Return(run) - return _c -} - -// NewMonitoringEndpointGenerator creates a new instance of MonitoringEndpointGenerator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMonitoringEndpointGenerator(t interface { - mock.TestingT - Cleanup(func()) -}) *MonitoringEndpointGenerator { - mock := &MonitoringEndpointGenerator{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/internal/mocks/prometheus_backend.go b/core/internal/mocks/prometheus_backend.go new file mode 100644 index 00000000000..d02f7062cbf --- /dev/null +++ b/core/internal/mocks/prometheus_backend.go @@ -0,0 +1,204 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + big "math/big" + + mock "github.com/stretchr/testify/mock" +) + +// PrometheusBackend is an autogenerated mock type for the PrometheusBackend type +type PrometheusBackend struct { + mock.Mock +} + +type PrometheusBackend_Expecter struct { + mock *mock.Mock +} + +func (_m *PrometheusBackend) EXPECT() *PrometheusBackend_Expecter { + return &PrometheusBackend_Expecter{mock: &_m.Mock} +} + +// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1 +func (_m *PrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) { + _m.Called(_a0, _a1) +} + +// PrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge' +type PrometheusBackend_SetMaxUnconfirmedAge_Call struct { + *mock.Call +} + +// SetMaxUnconfirmedAge is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 float64 +func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedAge_Call { + return &PrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)} +} + +func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(float64)) + }) + return _c +} + +func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *PrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Return() + return _c +} + +func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Return(run) + return _c +} + +// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1 +func (_m *PrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) { + _m.Called(_a0, _a1) +} + +// PrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks' +type PrometheusBackend_SetMaxUnconfirmedBlocks_Call struct { + *mock.Call +} + +// SetMaxUnconfirmedBlocks is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 int64 +func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { + return &PrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)} +} + +func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int64)) + }) + return _c +} + +func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Return() + return _c +} + +func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Return(run) + return _c +} + +// SetPipelineRunsQueued provides a mock function with given fields: n +func (_m *PrometheusBackend) SetPipelineRunsQueued(n int) { + _m.Called(n) +} + +// PrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued' +type PrometheusBackend_SetPipelineRunsQueued_Call struct { + *mock.Call +} + +// SetPipelineRunsQueued is a helper method to define mock.On call +// - n int +func (_e *PrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *PrometheusBackend_SetPipelineRunsQueued_Call { + return &PrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)} +} + +func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Return() *PrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Return() + return _c +} + +func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Return(run) + return _c +} + +// SetPipelineTaskRunsQueued provides a mock function with given fields: n +func (_m *PrometheusBackend) SetPipelineTaskRunsQueued(n int) { + _m.Called(n) +} + +// PrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued' +type PrometheusBackend_SetPipelineTaskRunsQueued_Call struct { + *mock.Call +} + +// SetPipelineTaskRunsQueued is a helper method to define mock.On call +// - n int +func (_e *PrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { + return &PrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)} +} + +func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *PrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Return() + return _c +} + +func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Return(run) + return _c +} + +// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1 +func (_m *PrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) { + _m.Called(_a0, _a1) +} + +// PrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions' +type PrometheusBackend_SetUnconfirmedTransactions_Call struct { + *mock.Call +} + +// SetUnconfirmedTransactions is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 int64 +func (_e *PrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetUnconfirmedTransactions_Call { + return &PrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)} +} + +func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int64)) + }) + return _c +} + +func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Return() *PrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Return() + return _c +} + +func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Return(run) + return _c +} + +// NewPrometheusBackend creates a new instance of PrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPrometheusBackend(t interface { + mock.TestingT + Cleanup(func()) +}) *PrometheusBackend { + mock := &PrometheusBackend{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index d305bc1e9cb..2268bd6553a 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -6,7 +6,6 @@ import ( "fmt" "math/big" "net/http" - "slices" "sync" "github.com/ethereum/go-ethereum/common" @@ -26,8 +25,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/standardcapabilities" "github.com/smartcontractkit/chainlink/v2/core/static" @@ -52,6 +49,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/feeds" "github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2" "github.com/smartcontractkit/chainlink/v2/core/services/gateway" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -329,6 +327,8 @@ func NewApplication(opts ApplicationOpts) (Application, error) { srvcs = append(srvcs, mailMon) srvcs = append(srvcs, relayerChainInterops.Services()...) + headReporter := headreporter.NewHeadReporterService(cfg.HeadReport(), opts.DS, legacyEVMChains, globalLogger, telemetryManager) + srvcs = append(srvcs, headReporter) // Initialize Local Users ORM and Authentication Provider specified in config // BasicAdminUsersORM is initialized and required regardless of separate Authentication Provider @@ -368,21 +368,8 @@ func NewApplication(opts ApplicationOpts) (Application, error) { workflowORM = workflowstore.NewDBStore(opts.DS, globalLogger, clockwork.NewRealClock()) ) - promReporter := headreporter.NewPrometheusReporter(opts.DS, legacyEVMChains) - var headReporter *headreporter.HeadReporterService - if slices.ContainsFunc(legacyEVMChains.Slice(), func(chain legacyevm.Chain) bool { - return chain.Config().EVM().HeadTracker().TelemetryEnabled() - }) { - telemReporter := headreporter.NewTelemetryReporter(legacyEVMChains, telemetryManager) - headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) - } else { - headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter) - } - for _, chain := range legacyEVMChains.Slice() { - if chain.Config().EVM().HeadTracker().TelemetryEnabled() { - chain.HeadBroadcaster().Subscribe(headReporter) - } + chain.HeadBroadcaster().Subscribe(headReporter) chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun) } diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index 5b6b839fb5e..abdd48d7592 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -483,6 +483,12 @@ func (g *generalConfig) RootDir() string { return h } +func (g *generalConfig) HeadReport() coreconfig.HeadReport { + return &headReport{ + h: g.c.HeadReport, + } +} + func (g *generalConfig) TelemetryIngress() coreconfig.TelemetryIngress { return &telemetryIngressConfig{ c: g.c.TelemetryIngress, diff --git a/core/services/chainlink/config_general_test.go b/core/services/chainlink/config_general_test.go index 29393ee0fdd..6247ebd91c8 100644 --- a/core/services/chainlink/config_general_test.go +++ b/core/services/chainlink/config_general_test.go @@ -30,6 +30,7 @@ func TestTOMLGeneralConfig_Defaults(t *testing.T) { assert.False(t, config.StarkNetEnabled()) assert.Equal(t, false, config.JobPipeline().ExternalInitiatorsEnabled()) assert.Equal(t, 15*time.Minute, config.WebServer().SessionTimeout().Duration()) + assert.Equal(t, false, config.HeadReport().TelemetryEnabled()) } func TestTOMLGeneralConfig_InsecureConfig(t *testing.T) { diff --git a/core/services/chainlink/config_head_report.go b/core/services/chainlink/config_head_report.go new file mode 100644 index 00000000000..e6e292938d9 --- /dev/null +++ b/core/services/chainlink/config_head_report.go @@ -0,0 +1,13 @@ +package chainlink + +import ( + "github.com/smartcontractkit/chainlink/v2/core/config/toml" +) + +type headReport struct { + h toml.HeadReport +} + +func (h headReport) TelemetryEnabled() bool { + return *h.h.TelemetryEnabled +} diff --git a/core/services/chainlink/config_head_report_test.go b/core/services/chainlink/config_head_report_test.go new file mode 100644 index 00000000000..1840c4f578b --- /dev/null +++ b/core/services/chainlink/config_head_report_test.go @@ -0,0 +1,18 @@ +package chainlink + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestHeadReportConfig(t *testing.T) { + opts := GeneralConfigOpts{ + ConfigStrings: []string{fullTOML}, + } + cfg, err := opts.New() + require.NoError(t, err) + + hr := cfg.HeadReport() + require.True(t, hr.TelemetryEnabled()) +} diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 40d62c1b921..bd75e92b23b 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -587,7 +587,6 @@ func TestConfig_Marshal(t *testing.T) { SamplingInterval: &hour, FinalityTagBypass: ptr[bool](false), MaxAllowedFinalityDepth: ptr[uint32](1500), - TelemetryEnabled: ptr[bool](true), }, NodePool: evmcfg.NodePool{ @@ -734,6 +733,9 @@ func TestConfig_Marshal(t *testing.T) { }, VerboseLogging: ptr(true), } + full.HeadReport = toml.HeadReport{ + TelemetryEnabled: ptr(true), + } for _, tt := range []struct { name string config Config @@ -1055,7 +1057,6 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 1500 FinalityTagBypass = false -TelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' @@ -1205,6 +1206,9 @@ CertFile = '/path/to/cert.pem' [Mercury.Transmitter] TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' +`}, + {"HeadReport", Config{Core: toml.Core{HeadReport: full.HeadReport}}, `[HeadReport] +TelemetryEnabled = true `}, {"full", full, fullTOML}, {"multi-chain", multiChain, multiChainTOML}, diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index c42ed5c7014..ae2e73768b6 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -692,6 +692,26 @@ func (_c *GeneralConfig_FluxMonitor_Call) RunAndReturn(run func() config.FluxMon return _c } +// HeadReport provides a mock function with given fields: +func (_m *GeneralConfig) HeadReport() config.HeadReport { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for HeadReport") + } + + var r0 config.HeadReport + if rf, ok := ret.Get(0).(func() config.HeadReport); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(config.HeadReport) + } + } + + return r0 +} + // Insecure provides a mock function with given fields: func (_m *GeneralConfig) Insecure() config.Insecure { ret := _m.Called() diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 63053c9bf64..60381c0d479 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -8,7 +8,7 @@ import ( "sync" "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" + relay "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters" @@ -119,6 +119,7 @@ func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfi if err2 != nil { return fmt.Errorf("failed to setup EVM relayer: %w", err2) } + legacyMap := make(map[string]legacyevm.Chain) for id, a := range adapters { // adapter is a service diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go index 883c6310466..5aaf6e16dd4 100644 --- a/core/services/chainlink/relayer_chain_interoperators_test.go +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -351,14 +351,9 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { assert.Equal(t, cnt, len(allChainsStats)) assert.Len(t, cr.Slice(), expectedChainCnt) - // should be one relayer per chain + // should be one relayer per chain and one service per relayer assert.Len(t, cr.Slice(), expectedChainCnt) - // if we have evm chain, then we have head_reporter as extra service - if tt.expectedEVMChainCnt > 0 { - assert.Len(t, cr.Services(), expectedChainCnt+1) - } else { - assert.Len(t, cr.Services(), expectedChainCnt) - } + assert.Len(t, cr.Services(), expectedChainCnt) expectedNodeCnt := tt.expectedEVMNodeCnt + tt.expectedCosmosNodeCnt + tt.expectedSolanaNodeCnt + tt.expectedStarknetNodeCnt allNodeStats, cnt, err := cr.NodeStatuses(testctx, 0, 0) diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index f1325d824ea..93a5e509ab1 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -237,6 +237,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 6543cf08b67..b2c342f33c7 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -247,6 +247,9 @@ CertFile = '/path/to/cert.pem' TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' +[HeadReport] +TelemetryEnabled = true + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 @@ -347,7 +350,6 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 1500 FinalityTagBypass = false -TelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 39f579f9fd7..f97e31f5b7d 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -237,6 +237,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -324,7 +327,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -425,7 +427,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -520,7 +521,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/core/services/relay/evm/headreporter/head_reporter.go b/core/services/headreporter/head_reporter.go similarity index 52% rename from core/services/relay/evm/headreporter/head_reporter.go rename to core/services/headreporter/head_reporter.go index e99888c8128..c2dee2c015d 100644 --- a/core/services/relay/evm/headreporter/head_reporter.go +++ b/core/services/headreporter/head_reporter.go @@ -5,15 +5,19 @@ import ( "sync" "time" - "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink/v2/core/config" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" ) +//go:generate mockery --quiet --name HeadReporter --output ../../internal/mocks/ --case=underscore type ( HeadReporter interface { ReportNewHead(ctx context.Context, head *evmtypes.Head) error @@ -22,30 +26,47 @@ type ( HeadReporterService struct { services.StateMachine - ds sqlutil.DataSource - lggr logger.Logger - newHeads *mailbox.Mailbox[*evmtypes.Head] - chStop services.StopChan - wgDone sync.WaitGroup - reportPeriod time.Duration - reporters []HeadReporter - unsubscribeFns []func() + ds sqlutil.DataSource + chains legacyevm.LegacyChainContainer + lggr logger.Logger + newHeads *mailbox.Mailbox[*evmtypes.Head] + chStop services.StopChan + wgDone sync.WaitGroup + reportPeriod time.Duration + reporters []HeadReporter } ) -func NewHeadReporterService(ds sqlutil.DataSource, lggr logger.Logger, reporters ...HeadReporter) *HeadReporterService { - return &HeadReporterService{ - ds: ds, - lggr: lggr.Named("HeadReporter"), - newHeads: mailbox.NewSingle[*evmtypes.Head](), - chStop: make(chan struct{}), - reporters: reporters, +func NewHeadReporterService(config config.HeadReport, ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, opts ...interface{}) *HeadReporterService { + reporters := make([]HeadReporter, 1, 2) + reporters[0] = NewPrometheusReporter(ds, chainContainer, lggr, opts) + if config.TelemetryEnabled() { + reporters = append(reporters, NewTelemetryReporter(chainContainer, lggr, monitoringEndpointGen)) } + return NewHeadReporterServiceWithReporters(ds, chainContainer, lggr, reporters, opts) } -func (hrd *HeadReporterService) Subscribe(subFn func(types.HeadTrackable) (evmtypes.Head, func())) { - _, unsubscribe := subFn(hrd) - hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe) +func NewHeadReporterServiceWithReporters(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, reporters []HeadReporter, opts ...interface{}) *HeadReporterService { + reportPeriod := 30 * time.Second + for _, opt := range opts { + switch v := opt.(type) { + case time.Duration: + reportPeriod = v + default: + lggr.Debugf("Unknown opt type '%T' passed to HeadReporterService", v) + } + } + chStop := make(chan struct{}) + return &HeadReporterService{ + ds: ds, + chains: chainContainer, + lggr: lggr.Named("HeadReporterService"), + newHeads: mailbox.NewSingle[*evmtypes.Head](), + chStop: chStop, + wgDone: sync.WaitGroup{}, + reportPeriod: reportPeriod, + reporters: reporters, + } } func (hrd *HeadReporterService) Start(context.Context) error { diff --git a/core/services/headreporter/head_reporter_test.go b/core/services/headreporter/head_reporter_test.go new file mode 100644 index 00000000000..25f10d1c118 --- /dev/null +++ b/core/services/headreporter/head_reporter_test.go @@ -0,0 +1,93 @@ +package headreporter_test + +import ( + "sync/atomic" + "testing" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + + "github.com/jmoiron/sqlx" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" +) + +func newHead() evmtypes.Head { + return evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(0)} +} + +func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { + config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) + keyStore := cltest.NewKeyStore(t, db).Eth() + ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) + require.NoError(t, err) + lggr := logger.TestLogger(t) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts) + + txm, err := txmgr.NewTxm( + db, + evmConfig, + evmConfig.GasEstimator(), + evmConfig.Transactions(), + nil, + dbConfig, + dbConfig.Listener(), + ethClient, + lggr, + lp, + keyStore, + estimator) + require.NoError(t, err) + + cfg := configtest.NewGeneralConfig(t, nil) + return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) +} + +func Test_HeadReporterService(t *testing.T) { + t.Run("report everything", func(t *testing.T) { + db := pgtest.NewSqlxDB(t) + + headReporter := mocks.NewHeadReporter(t) + service := headreporter.NewHeadReporterServiceWithReporters(db, newLegacyChainContainer(t, db), logger.TestLogger(t), []headreporter.HeadReporter{headReporter}, time.Second) + err := service.Start(testutils.Context(t)) + require.NoError(t, err) + + var reportCalls atomic.Int32 + head := newHead() + headReporter.On("ReportNewHead", mock.Anything, &head).Run(func(args mock.Arguments) { + reportCalls.Add(1) + }).Return(nil) + headReporter.On("ReportPeriodic", mock.Anything).Run(func(args mock.Arguments) { + reportCalls.Add(1) + }).Return(nil) + service.OnNewLongestChain(testutils.Context(t), &head) + + require.Eventually(t, func() bool { return reportCalls.Load() == 2 }, 5*time.Second, 100*time.Millisecond) + }) +} diff --git a/core/services/relay/evm/headreporter/prometheus_reporter.go b/core/services/headreporter/prometheus_reporter.go similarity index 94% rename from core/services/relay/evm/headreporter/prometheus_reporter.go rename to core/services/headreporter/prometheus_reporter.go index 3e39c7aca45..5d8cf42bc49 100644 --- a/core/services/relay/evm/headreporter/prometheus_reporter.go +++ b/core/services/headreporter/prometheus_reporter.go @@ -16,6 +16,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" ) type ( @@ -59,11 +60,20 @@ var ( }) ) -func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer) *prometheusReporter { +func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) HeadReporter { + var backend PrometheusBackend = defaultBackend{} + for _, opt := range opts { + switch v := opt.(type) { + case PrometheusBackend: + backend = v + default: + lggr.Debugf("Unknown opt type '%T' passed to PrometheusReporter", v) + } + } return &prometheusReporter{ ds: ds, chains: chainContainer, - backend: defaultBackend{}, + backend: backend, } } diff --git a/core/services/relay/evm/headreporter/prometheus_reporter_test.go b/core/services/headreporter/prometheus_reporter_test.go similarity index 59% rename from core/services/relay/evm/headreporter/prometheus_reporter_test.go rename to core/services/headreporter/prometheus_reporter_test.go index 092b67fd997..131805cd7a5 100644 --- a/core/services/relay/evm/headreporter/prometheus_reporter_test.go +++ b/core/services/headreporter/prometheus_reporter_test.go @@ -3,39 +3,31 @@ package headreporter_test import ( "math/big" "testing" - "time" - "github.com/jmoiron/sqlx" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" ) func Test_PrometheusReporter(t *testing.T) { t.Run("with nothing in the database", func(t *testing.T) { db := pgtest.NewSqlxDB(t) - backend := headreporter.NewMockPrometheusBackend(t) - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) - reporter.SetBackend(backend) + backend := mocks.NewPrometheusBackend(t) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - head := headreporter.NewHead() + head := newHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -56,17 +48,16 @@ func Test_PrometheusReporter(t *testing.T) { cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7)) - backend := headreporter.NewMockPrometheusBackend(t) + backend := mocks.NewPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(3)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), mock.MatchedBy(func(s float64) bool { return s > 0 })).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(35)).Return() - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) - reporter.SetBackend(backend) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) - head := headreporter.NewHead() + head := newHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -85,15 +76,14 @@ func Test_PrometheusReporter(t *testing.T) { cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 2) - backend := headreporter.NewMockPrometheusBackend(t) + backend := mocks.NewPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) - reporter.SetBackend(backend) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) - head := headreporter.NewHead() + head := newHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -104,39 +94,3 @@ func Test_PrometheusReporter(t *testing.T) { require.NoError(t, err) }) } - -func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { - config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) - keyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) - require.NoError(t, err) - lggr := logger.TestLogger(t) - lpOpts := logpoller.Opts{ - PollPeriod: 100 * time.Millisecond, - FinalityDepth: 2, - BackfillBatchSize: 3, - RpcBatchSize: 2, - KeepFinalizedBlocksDepth: 1000, - } - ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts) - - txm, err := txmgr.NewTxm( - db, - evmConfig, - evmConfig.GasEstimator(), - evmConfig.Transactions(), - nil, - dbConfig, - dbConfig.Listener(), - ethClient, - lggr, - lp, - keyStore, - estimator) - require.NoError(t, err) - - cfg := configtest.NewGeneralConfig(t, nil) - return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) -} diff --git a/core/services/relay/evm/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go similarity index 93% rename from core/services/relay/evm/headreporter/telemetry_reporter.go rename to core/services/headreporter/telemetry_reporter.go index e3d8e096084..241296a7e46 100644 --- a/core/services/relay/evm/headreporter/telemetry_reporter.go +++ b/core/services/headreporter/telemetry_reporter.go @@ -10,6 +10,7 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" @@ -21,7 +22,7 @@ type ( } ) -func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { +func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { endpoints := make(map[uint64]commontypes.MonitoringEndpoint) for _, chain := range chainContainer.Slice() { endpoints[chain.ID().Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chain.ID().String(), "", synchronization.HeadReport) diff --git a/core/services/relay/evm/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go similarity index 88% rename from core/services/relay/evm/headreporter/telemetry_reporter_test.go rename to core/services/headreporter/telemetry_reporter_test.go index 103a2b27f92..bfb24d8ed01 100644 --- a/core/services/relay/evm/headreporter/telemetry_reporter_test.go +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -14,11 +14,12 @@ import ( ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" - mocks2 "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/headreporter" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" + mocks2 "github.com/smartcontractkit/chainlink/v2/core/services/telemetry/mocks" ) type IngressAgent struct { @@ -53,7 +54,7 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(ingressAgent) - reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) head := evmtypes.Head{ Number: 42, @@ -100,7 +101,7 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(ingressAgent) - reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) head := evmtypes.Head{ Number: 42, @@ -135,7 +136,7 @@ func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(nil) - reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) head := evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(100)} diff --git a/core/services/relay/evm/headreporter/head_reporter_test.go b/core/services/relay/evm/headreporter/head_reporter_test.go deleted file mode 100644 index ded7e1fb61b..00000000000 --- a/core/services/relay/evm/headreporter/head_reporter_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package headreporter - -import ( - "sync/atomic" - "testing" - "time" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -func NewHead() evmtypes.Head { - return evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(0)} -} - -func Test_HeadReporterService(t *testing.T) { - t.Run("report everything", func(t *testing.T) { - db := pgtest.NewSqlxDB(t) - - headReporter := NewMockHeadReporter(t) - service := NewHeadReporterService(db, logger.TestLogger(t), headReporter) - service.reportPeriod = time.Second - err := service.Start(testutils.Context(t)) - require.NoError(t, err) - - var reportCalls atomic.Int32 - head := NewHead() - headReporter.On("ReportNewHead", mock.Anything, &head).Run(func(args mock.Arguments) { - reportCalls.Add(1) - }).Return(nil) - headReporter.On("ReportPeriodic", mock.Anything).Run(func(args mock.Arguments) { - reportCalls.Add(1) - }).Return(nil) - service.OnNewLongestChain(testutils.Context(t), &head) - - require.Eventually(t, func() bool { return reportCalls.Load() == 2 }, 5*time.Second, 100*time.Millisecond) - }) -} diff --git a/core/services/relay/evm/headreporter/helper_test.go b/core/services/relay/evm/headreporter/helper_test.go deleted file mode 100644 index fa05182a851..00000000000 --- a/core/services/relay/evm/headreporter/helper_test.go +++ /dev/null @@ -1,5 +0,0 @@ -package headreporter - -func (p *prometheusReporter) SetBackend(b PrometheusBackend) { - p.backend = b -} diff --git a/core/services/relay/evm/headreporter/mock_head_reporter_test.go b/core/services/relay/evm/headreporter/mock_head_reporter_test.go deleted file mode 100644 index 21978abb86a..00000000000 --- a/core/services/relay/evm/headreporter/mock_head_reporter_test.go +++ /dev/null @@ -1,130 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package headreporter - -import ( - context "context" - - types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - mock "github.com/stretchr/testify/mock" -) - -// MockHeadReporter is an autogenerated mock type for the HeadReporter type -type MockHeadReporter struct { - mock.Mock -} - -type MockHeadReporter_Expecter struct { - mock *mock.Mock -} - -func (_m *MockHeadReporter) EXPECT() *MockHeadReporter_Expecter { - return &MockHeadReporter_Expecter{mock: &_m.Mock} -} - -// ReportNewHead provides a mock function with given fields: ctx, head -func (_m *MockHeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { - ret := _m.Called(ctx, head) - - if len(ret) == 0 { - panic("no return value specified for ReportNewHead") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok { - r0 = rf(ctx, head) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockHeadReporter_ReportNewHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportNewHead' -type MockHeadReporter_ReportNewHead_Call struct { - *mock.Call -} - -// ReportNewHead is a helper method to define mock.On call -// - ctx context.Context -// - head *types.Head -func (_e *MockHeadReporter_Expecter) ReportNewHead(ctx interface{}, head interface{}) *MockHeadReporter_ReportNewHead_Call { - return &MockHeadReporter_ReportNewHead_Call{Call: _e.mock.On("ReportNewHead", ctx, head)} -} - -func (_c *MockHeadReporter_ReportNewHead_Call) Run(run func(ctx context.Context, head *types.Head)) *MockHeadReporter_ReportNewHead_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*types.Head)) - }) - return _c -} - -func (_c *MockHeadReporter_ReportNewHead_Call) Return(_a0 error) *MockHeadReporter_ReportNewHead_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockHeadReporter_ReportNewHead_Call) RunAndReturn(run func(context.Context, *types.Head) error) *MockHeadReporter_ReportNewHead_Call { - _c.Call.Return(run) - return _c -} - -// ReportPeriodic provides a mock function with given fields: ctx -func (_m *MockHeadReporter) ReportPeriodic(ctx context.Context) error { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ReportPeriodic") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockHeadReporter_ReportPeriodic_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportPeriodic' -type MockHeadReporter_ReportPeriodic_Call struct { - *mock.Call -} - -// ReportPeriodic is a helper method to define mock.On call -// - ctx context.Context -func (_e *MockHeadReporter_Expecter) ReportPeriodic(ctx interface{}) *MockHeadReporter_ReportPeriodic_Call { - return &MockHeadReporter_ReportPeriodic_Call{Call: _e.mock.On("ReportPeriodic", ctx)} -} - -func (_c *MockHeadReporter_ReportPeriodic_Call) Run(run func(ctx context.Context)) *MockHeadReporter_ReportPeriodic_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *MockHeadReporter_ReportPeriodic_Call) Return(_a0 error) *MockHeadReporter_ReportPeriodic_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockHeadReporter_ReportPeriodic_Call) RunAndReturn(run func(context.Context) error) *MockHeadReporter_ReportPeriodic_Call { - _c.Call.Return(run) - return _c -} - -// NewMockHeadReporter creates a new instance of MockHeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockHeadReporter(t interface { - mock.TestingT - Cleanup(func()) -}) *MockHeadReporter { - mock := &MockHeadReporter{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/services/relay/evm/headreporter/mock_prometheus_backend_test.go b/core/services/relay/evm/headreporter/mock_prometheus_backend_test.go deleted file mode 100644 index ca83f6c4fbb..00000000000 --- a/core/services/relay/evm/headreporter/mock_prometheus_backend_test.go +++ /dev/null @@ -1,204 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package headreporter - -import ( - big "math/big" - - mock "github.com/stretchr/testify/mock" -) - -// MockPrometheusBackend is an autogenerated mock type for the PrometheusBackend type -type MockPrometheusBackend struct { - mock.Mock -} - -type MockPrometheusBackend_Expecter struct { - mock *mock.Mock -} - -func (_m *MockPrometheusBackend) EXPECT() *MockPrometheusBackend_Expecter { - return &MockPrometheusBackend_Expecter{mock: &_m.Mock} -} - -// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1 -func (_m *MockPrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) { - _m.Called(_a0, _a1) -} - -// MockPrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge' -type MockPrometheusBackend_SetMaxUnconfirmedAge_Call struct { - *mock.Call -} - -// SetMaxUnconfirmedAge is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 float64 -func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { - return &MockPrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)} -} - -func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(float64)) - }) - return _c -} - -func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Return() - return _c -} - -func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Return(run) - return _c -} - -// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1 -func (_m *MockPrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) { - _m.Called(_a0, _a1) -} - -// MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks' -type MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call struct { - *mock.Call -} - -// SetMaxUnconfirmedBlocks is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 int64 -func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { - return &MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)} -} - -func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(int64)) - }) - return _c -} - -func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Return() - return _c -} - -func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Return(run) - return _c -} - -// SetPipelineRunsQueued provides a mock function with given fields: n -func (_m *MockPrometheusBackend) SetPipelineRunsQueued(n int) { - _m.Called(n) -} - -// MockPrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued' -type MockPrometheusBackend_SetPipelineRunsQueued_Call struct { - *mock.Call -} - -// SetPipelineRunsQueued is a helper method to define mock.On call -// - n int -func (_e *MockPrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineRunsQueued_Call { - return &MockPrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)} -} - -func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Return() - return _c -} - -func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Return(run) - return _c -} - -// SetPipelineTaskRunsQueued provides a mock function with given fields: n -func (_m *MockPrometheusBackend) SetPipelineTaskRunsQueued(n int) { - _m.Called(n) -} - -// MockPrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued' -type MockPrometheusBackend_SetPipelineTaskRunsQueued_Call struct { - *mock.Call -} - -// SetPipelineTaskRunsQueued is a helper method to define mock.On call -// - n int -func (_e *MockPrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { - return &MockPrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)} -} - -func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Return() - return _c -} - -func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Return(run) - return _c -} - -// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1 -func (_m *MockPrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) { - _m.Called(_a0, _a1) -} - -// MockPrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions' -type MockPrometheusBackend_SetUnconfirmedTransactions_Call struct { - *mock.Call -} - -// SetUnconfirmedTransactions is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 int64 -func (_e *MockPrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { - return &MockPrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)} -} - -func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(int64)) - }) - return _c -} - -func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Return() *MockPrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Return() - return _c -} - -func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Return(run) - return _c -} - -// NewMockPrometheusBackend creates a new instance of MockPrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockPrometheusBackend(t interface { - mock.TestingT - Cleanup(func()) -}) *MockPrometheusBackend { - mock := &MockPrometheusBackend{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/services/telemetry/common.go b/core/services/telemetry/common.go index 37a92f16c6d..1ccd9674589 100644 --- a/core/services/telemetry/common.go +++ b/core/services/telemetry/common.go @@ -6,6 +6,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" ) +//go:generate mockery --quiet --name MonitoringEndpointGenerator --output ./mocks --case=underscore type MonitoringEndpointGenerator interface { GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) ocrtypes.MonitoringEndpoint } diff --git a/core/services/telemetry/mocks/monitoring_endpoint_generator.go b/core/services/telemetry/mocks/monitoring_endpoint_generator.go new file mode 100644 index 00000000000..717654f404f --- /dev/null +++ b/core/services/telemetry/mocks/monitoring_endpoint_generator.go @@ -0,0 +1,49 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + commontypes "github.com/smartcontractkit/libocr/commontypes" + mock "github.com/stretchr/testify/mock" + + synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" +) + +// MonitoringEndpointGenerator is an autogenerated mock type for the MonitoringEndpointGenerator type +type MonitoringEndpointGenerator struct { + mock.Mock +} + +// GenMonitoringEndpoint provides a mock function with given fields: network, chainID, contractID, telemType +func (_m *MonitoringEndpointGenerator) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { + ret := _m.Called(network, chainID, contractID, telemType) + + if len(ret) == 0 { + panic("no return value specified for GenMonitoringEndpoint") + } + + var r0 commontypes.MonitoringEndpoint + if rf, ok := ret.Get(0).(func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint); ok { + r0 = rf(network, chainID, contractID, telemType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(commontypes.MonitoringEndpoint) + } + } + + return r0 +} + +// NewMonitoringEndpointGenerator creates a new instance of MonitoringEndpointGenerator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMonitoringEndpointGenerator(t interface { + mock.TestingT + Cleanup(func()) +}) *MonitoringEndpointGenerator { + mock := &MonitoringEndpointGenerator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index f1325d824ea..93a5e509ab1 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -237,6 +237,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 1ec0302e0ae..ab6d0ab8447 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -247,6 +247,9 @@ CertFile = '' TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' +[HeadReport] +TelemetryEnabled = true + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 @@ -346,7 +349,6 @@ MaxBufferSize = 17 SamplingInterval = '1h0m0s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index ad7dcd6c160..5bf08c78346 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -237,6 +237,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -324,7 +327,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -425,7 +427,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 @@ -520,7 +521,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index cda4019bb36..c2270599d00 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1768,6 +1768,19 @@ TransmitTimeout controls how long the transmitter will wait for a response when sending a message to the mercury server, before aborting and considering the transmission to be failed. +## HeadReport +```toml +[HeadReport] +TelemetryEnabled = false # Default +``` + + +### TelemetryEnabled +```toml +TelemetryEnabled = false # Default +``` +TelemetryEnabled controls if it collects information about new blocks from blockchain + ## EVM EVM defaults depend on ChainID: @@ -1839,7 +1852,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -1934,7 +1946,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2029,7 +2040,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2124,7 +2134,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2220,7 +2229,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2315,7 +2323,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2410,7 +2417,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2506,7 +2512,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2601,7 +2606,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2695,7 +2699,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2789,7 +2792,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2884,7 +2886,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -2980,7 +2981,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3075,7 +3075,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3170,7 +3169,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3265,7 +3263,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3360,7 +3357,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3455,7 +3451,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3550,7 +3545,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3645,7 +3639,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3740,7 +3733,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3835,7 +3827,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -3931,7 +3922,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4026,7 +4016,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4120,7 +4109,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4215,7 +4203,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4310,7 +4297,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4405,7 +4391,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4500,7 +4485,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4594,7 +4578,6 @@ MaxBufferSize = 100 SamplingInterval = '0s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4689,7 +4672,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4784,7 +4766,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4879,7 +4860,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -4974,7 +4954,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5068,7 +5047,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5163,7 +5141,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5258,7 +5235,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5544,7 +5520,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5639,7 +5614,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5734,7 +5708,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5829,7 +5802,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -5924,7 +5896,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6018,7 +5989,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6112,7 +6082,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6206,7 +6175,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6301,7 +6269,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6396,7 +6363,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6490,7 +6456,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6585,7 +6550,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6680,7 +6644,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6776,7 +6739,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6872,7 +6834,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -6967,7 +6928,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7062,7 +7022,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7157,7 +7116,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7252,7 +7210,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = false -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7347,7 +7304,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7442,7 +7398,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -7537,7 +7492,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [NodePool] PollFailureThreshold = 5 @@ -8193,7 +8147,6 @@ MaxBufferSize = 3 # Default SamplingInterval = '1s' # Default FinalityTagBypass = true # Default MaxAllowedFinalityDepth = 10000 # Default -TelemetryEnabled = false # Default ``` The head tracker continually listens for new heads from the chain. @@ -8240,12 +8193,6 @@ MaxAllowedFinalityDepth - defines maximum number of blocks between the most rece If actual finality depth exceeds this number, HeadTracker aborts backfill and returns an error. Has no effect if `FinalityTagsEnabled` = false -### TelemetryEnabled -```toml -TelemetryEnabled = false # Default -``` -TelemetryEnabled controls if it collects information about new blocks from blockchain - ## EVM.KeySpecific ```toml [[EVM.KeySpecific]] diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index ff8b4889c49..10897c897c7 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -249,6 +249,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index d444abaa38e..c25e5662daf 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -293,6 +293,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -380,7 +383,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 094bd418e9c..9b7410df901 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -293,6 +293,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -380,7 +383,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 4844a48b8c6..302700174b5 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -293,6 +293,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -380,7 +383,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 0cdf001eccd..6fa9ca932a8 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -278,6 +278,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index d37dade3064..99410d91078 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -283,6 +283,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -370,7 +373,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index 8134c5473fb..d11377ec74a 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -290,6 +290,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 @@ -377,7 +380,6 @@ MaxBufferSize = 3 SamplingInterval = '1s' MaxAllowedFinalityDepth = 10000 FinalityTagBypass = true -TelemetryEnabled = false [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index dea40ec8da0..9d27734d058 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -272,6 +272,9 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' +[HeadReport] +TelemetryEnabled = false + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 From e07e3f6911b591db350f13b0087bbc27ba7b4320 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Tue, 6 Aug 2024 18:39:33 +0100 Subject: [PATCH 09/21] review --- core/services/chainlink/application.go | 11 +++- core/services/headreporter/head_reporter.go | 61 ++++++------------- .../headreporter/prometheus_reporter.go | 14 +---- .../headreporter/telemetry_reporter.go | 3 +- .../headreporter/telemetry_reporter_test.go | 7 +-- 5 files changed, 35 insertions(+), 61 deletions(-) diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 2268bd6553a..5dc12a7defc 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -327,8 +327,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) { srvcs = append(srvcs, mailMon) srvcs = append(srvcs, relayerChainInterops.Services()...) - headReporter := headreporter.NewHeadReporterService(cfg.HeadReport(), opts.DS, legacyEVMChains, globalLogger, telemetryManager) - srvcs = append(srvcs, headReporter) // Initialize Local Users ORM and Authentication Provider specified in config // BasicAdminUsersORM is initialized and required regardless of separate Authentication Provider @@ -368,6 +366,15 @@ func NewApplication(opts ApplicationOpts) (Application, error) { workflowORM = workflowstore.NewDBStore(opts.DS, globalLogger, clockwork.NewRealClock()) ) + promReporter := headreporter.NewPrometheusReporter(opts.DS, legacyEVMChains) + var headReporter *headreporter.HeadReporterService + if cfg.HeadReport().TelemetryEnabled() { + telemReporter := headreporter.NewTelemetryReporter(legacyEVMChains, telemetryManager) + headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) + } else { + headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter) + } + srvcs = append(srvcs, headReporter) for _, chain := range legacyEVMChains.Slice() { chain.HeadBroadcaster().Subscribe(headReporter) chain.TxManager().RegisterResumeCallback(pipelineRunner.ResumeRun) diff --git a/core/services/headreporter/head_reporter.go b/core/services/headreporter/head_reporter.go index c2dee2c015d..f81a6acf913 100644 --- a/core/services/headreporter/head_reporter.go +++ b/core/services/headreporter/head_reporter.go @@ -5,19 +5,15 @@ import ( "sync" "time" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - "github.com/smartcontractkit/chainlink/v2/core/config" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" ) -//go:generate mockery --quiet --name HeadReporter --output ../../internal/mocks/ --case=underscore type ( HeadReporter interface { ReportNewHead(ctx context.Context, head *evmtypes.Head) error @@ -26,47 +22,30 @@ type ( HeadReporterService struct { services.StateMachine - ds sqlutil.DataSource - chains legacyevm.LegacyChainContainer - lggr logger.Logger - newHeads *mailbox.Mailbox[*evmtypes.Head] - chStop services.StopChan - wgDone sync.WaitGroup - reportPeriod time.Duration - reporters []HeadReporter + ds sqlutil.DataSource + lggr logger.Logger + newHeads *mailbox.Mailbox[*evmtypes.Head] + chStop services.StopChan + wgDone sync.WaitGroup + reportPeriod time.Duration + reporters []HeadReporter + unsubscribeFns []func() } ) -func NewHeadReporterService(config config.HeadReport, ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator, opts ...interface{}) *HeadReporterService { - reporters := make([]HeadReporter, 1, 2) - reporters[0] = NewPrometheusReporter(ds, chainContainer, lggr, opts) - if config.TelemetryEnabled() { - reporters = append(reporters, NewTelemetryReporter(chainContainer, lggr, monitoringEndpointGen)) +func NewHeadReporterService(ds sqlutil.DataSource, lggr logger.Logger, reporters ...HeadReporter) *HeadReporterService { + return &HeadReporterService{ + ds: ds, + lggr: lggr.Named("HeadReporter"), + newHeads: mailbox.NewSingle[*evmtypes.Head](), + chStop: make(chan struct{}), + reporters: reporters, } - return NewHeadReporterServiceWithReporters(ds, chainContainer, lggr, reporters, opts) } -func NewHeadReporterServiceWithReporters(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, reporters []HeadReporter, opts ...interface{}) *HeadReporterService { - reportPeriod := 30 * time.Second - for _, opt := range opts { - switch v := opt.(type) { - case time.Duration: - reportPeriod = v - default: - lggr.Debugf("Unknown opt type '%T' passed to HeadReporterService", v) - } - } - chStop := make(chan struct{}) - return &HeadReporterService{ - ds: ds, - chains: chainContainer, - lggr: lggr.Named("HeadReporterService"), - newHeads: mailbox.NewSingle[*evmtypes.Head](), - chStop: chStop, - wgDone: sync.WaitGroup{}, - reportPeriod: reportPeriod, - reporters: reporters, - } +func (hrd *HeadReporterService) Subscribe(subFn func(types.HeadTrackable) (evmtypes.Head, func())) { + _, unsubscribe := subFn(hrd) + hrd.unsubscribeFns = append(hrd.unsubscribeFns, unsubscribe) } func (hrd *HeadReporterService) Start(context.Context) error { diff --git a/core/services/headreporter/prometheus_reporter.go b/core/services/headreporter/prometheus_reporter.go index 5d8cf42bc49..3e39c7aca45 100644 --- a/core/services/headreporter/prometheus_reporter.go +++ b/core/services/headreporter/prometheus_reporter.go @@ -16,7 +16,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) type ( @@ -60,20 +59,11 @@ var ( }) ) -func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) HeadReporter { - var backend PrometheusBackend = defaultBackend{} - for _, opt := range opts { - switch v := opt.(type) { - case PrometheusBackend: - backend = v - default: - lggr.Debugf("Unknown opt type '%T' passed to PrometheusReporter", v) - } - } +func NewPrometheusReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer) *prometheusReporter { return &prometheusReporter{ ds: ds, chains: chainContainer, - backend: backend, + backend: defaultBackend{}, } } diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go index 241296a7e46..e3d8e096084 100644 --- a/core/services/headreporter/telemetry_reporter.go +++ b/core/services/headreporter/telemetry_reporter.go @@ -10,7 +10,6 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" @@ -22,7 +21,7 @@ type ( } ) -func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { +func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { endpoints := make(map[uint64]commontypes.MonitoringEndpoint) for _, chain := range chainContainer.Slice() { endpoints[chain.ID().Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chain.ID().String(), "", synchronization.HeadReport) diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go index bfb24d8ed01..145a6329e80 100644 --- a/core/services/headreporter/telemetry_reporter_test.go +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -15,7 +15,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" @@ -54,7 +53,7 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(ingressAgent) - reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) head := evmtypes.Head{ Number: 42, @@ -101,7 +100,7 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(ingressAgent) - reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) head := evmtypes.Head{ Number: 42, @@ -136,7 +135,7 @@ func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(nil) - reporter := headreporter.NewTelemetryReporter(chains, logger.TestLogger(t), monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) head := evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(100)} From 88e54cddcc193d1389249d25b38ea475749b74a3 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Tue, 6 Aug 2024 19:02:18 +0100 Subject: [PATCH 10/21] review --- .mockery.yaml | 8 +- core/internal/mocks/head_reporter.go | 66 ------ core/internal/mocks/prometheus_backend.go | 204 ------------------ .../chainlink/mocks/general_config.go | 27 +++ .../headreporter/head_reporter_test.go | 64 +----- core/services/headreporter/helper_test.go | 5 + .../headreporter/mock_head_reporter_test.go | 130 +++++++++++ .../mock_prometheus_backend_test.go | 204 ++++++++++++++++++ .../headreporter/prometheus_reporter_test.go | 73 +++++-- core/services/telemetry/common.go | 1 - .../mocks/monitoring_endpoint_generator.go | 49 ----- 11 files changed, 440 insertions(+), 391 deletions(-) delete mode 100644 core/internal/mocks/head_reporter.go delete mode 100644 core/internal/mocks/prometheus_backend.go create mode 100644 core/services/headreporter/helper_test.go create mode 100644 core/services/headreporter/mock_head_reporter_test.go create mode 100644 core/services/headreporter/mock_prometheus_backend_test.go delete mode 100644 core/services/telemetry/mocks/monitoring_endpoint_generator.go diff --git a/.mockery.yaml b/.mockery.yaml index abb3105b136..7b15985b3ae 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -262,10 +262,14 @@ packages: ORM: Runner: PipelineParamUnmarshaler: - github.com/smartcontractkit/chainlink/v2/core/services/promreporter: + github.com/smartcontractkit/chainlink/v2/core/services/headreporter: config: - dir: core/internal/mocks + dir: "{{ .InterfaceDir }}" + filename: "mock_{{ .InterfaceName | snakecase }}_test.go" + inpackage: true + mockname: "Mock{{ .InterfaceName | camelcase }}" interfaces: + HeadReporter: PrometheusBackend: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm: interfaces: diff --git a/core/internal/mocks/head_reporter.go b/core/internal/mocks/head_reporter.go deleted file mode 100644 index 49e4e7f491d..00000000000 --- a/core/internal/mocks/head_reporter.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - context "context" - - mock "github.com/stretchr/testify/mock" - - types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" -) - -// HeadReporter is an autogenerated mock type for the HeadReporter type -type HeadReporter struct { - mock.Mock -} - -// ReportNewHead provides a mock function with given fields: ctx, head -func (_m *HeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { - ret := _m.Called(ctx, head) - - if len(ret) == 0 { - panic("no return value specified for ReportNewHead") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok { - r0 = rf(ctx, head) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ReportPeriodic provides a mock function with given fields: ctx -func (_m *HeadReporter) ReportPeriodic(ctx context.Context) error { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for ReportPeriodic") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// NewHeadReporter creates a new instance of HeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewHeadReporter(t interface { - mock.TestingT - Cleanup(func()) -}) *HeadReporter { - mock := &HeadReporter{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/internal/mocks/prometheus_backend.go b/core/internal/mocks/prometheus_backend.go deleted file mode 100644 index d02f7062cbf..00000000000 --- a/core/internal/mocks/prometheus_backend.go +++ /dev/null @@ -1,204 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - big "math/big" - - mock "github.com/stretchr/testify/mock" -) - -// PrometheusBackend is an autogenerated mock type for the PrometheusBackend type -type PrometheusBackend struct { - mock.Mock -} - -type PrometheusBackend_Expecter struct { - mock *mock.Mock -} - -func (_m *PrometheusBackend) EXPECT() *PrometheusBackend_Expecter { - return &PrometheusBackend_Expecter{mock: &_m.Mock} -} - -// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge' -type PrometheusBackend_SetMaxUnconfirmedAge_Call struct { - *mock.Call -} - -// SetMaxUnconfirmedAge is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 float64 -func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - return &PrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(float64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *PrometheusBackend_SetMaxUnconfirmedAge_Call { - _c.Call.Return(run) - return _c -} - -// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks' -type PrometheusBackend_SetMaxUnconfirmedBlocks_Call struct { - *mock.Call -} - -// SetMaxUnconfirmedBlocks is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 int64 -func (_e *PrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - return &PrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(int64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetMaxUnconfirmedBlocks_Call { - _c.Call.Return(run) - return _c -} - -// SetPipelineRunsQueued provides a mock function with given fields: n -func (_m *PrometheusBackend) SetPipelineRunsQueued(n int) { - _m.Called(n) -} - -// PrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued' -type PrometheusBackend_SetPipelineRunsQueued_Call struct { - *mock.Call -} - -// SetPipelineRunsQueued is a helper method to define mock.On call -// - n int -func (_e *PrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *PrometheusBackend_SetPipelineRunsQueued_Call { - return &PrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)} -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) Return() *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineRunsQueued_Call { - _c.Call.Return(run) - return _c -} - -// SetPipelineTaskRunsQueued provides a mock function with given fields: n -func (_m *PrometheusBackend) SetPipelineTaskRunsQueued(n int) { - _m.Called(n) -} - -// PrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued' -type PrometheusBackend_SetPipelineTaskRunsQueued_Call struct { - *mock.Call -} - -// SetPipelineTaskRunsQueued is a helper method to define mock.On call -// - n int -func (_e *PrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - return &PrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)} -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *PrometheusBackend_SetPipelineTaskRunsQueued_Call { - _c.Call.Return(run) - return _c -} - -// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1 -func (_m *PrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) { - _m.Called(_a0, _a1) -} - -// PrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions' -type PrometheusBackend_SetUnconfirmedTransactions_Call struct { - *mock.Call -} - -// SetUnconfirmedTransactions is a helper method to define mock.On call -// - _a0 *big.Int -// - _a1 int64 -func (_e *PrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *PrometheusBackend_SetUnconfirmedTransactions_Call { - return &PrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)} -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*big.Int), args[1].(int64)) - }) - return _c -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) Return() *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Return() - return _c -} - -func (_c *PrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *PrometheusBackend_SetUnconfirmedTransactions_Call { - _c.Call.Return(run) - return _c -} - -// NewPrometheusBackend creates a new instance of PrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewPrometheusBackend(t interface { - mock.TestingT - Cleanup(func()) -}) *PrometheusBackend { - mock := &PrometheusBackend{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index ae2e73768b6..f04ff40c566 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -712,6 +712,33 @@ func (_m *GeneralConfig) HeadReport() config.HeadReport { return r0 } +// GeneralConfig_HeadReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HeadReport' +type GeneralConfig_HeadReport_Call struct { + *mock.Call +} + +// HeadReport is a helper method to define mock.On call +func (_e *GeneralConfig_Expecter) HeadReport() *GeneralConfig_HeadReport_Call { + return &GeneralConfig_HeadReport_Call{Call: _e.mock.On("HeadReport")} +} + +func (_c *GeneralConfig_HeadReport_Call) Run(run func()) *GeneralConfig_HeadReport_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *GeneralConfig_HeadReport_Call) Return(_a0 config.HeadReport) *GeneralConfig_HeadReport_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GeneralConfig_HeadReport_Call) RunAndReturn(run func() config.HeadReport) *GeneralConfig_HeadReport_Call { + _c.Call.Return(run) + return _c +} + // Insecure provides a mock function with given fields: func (_m *GeneralConfig) Insecure() config.Insecure { ret := _m.Called() diff --git a/core/services/headreporter/head_reporter_test.go b/core/services/headreporter/head_reporter_test.go index 25f10d1c118..ded7e1fb61b 100644 --- a/core/services/headreporter/head_reporter_test.go +++ b/core/services/headreporter/head_reporter_test.go @@ -1,85 +1,37 @@ -package headreporter_test +package headreporter import ( "sync/atomic" "testing" "time" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" - - "github.com/jmoiron/sqlx" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" ) -func newHead() evmtypes.Head { +func NewHead() evmtypes.Head { return evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(0)} } -func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { - config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) - keyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) - require.NoError(t, err) - lggr := logger.TestLogger(t) - lpOpts := logpoller.Opts{ - PollPeriod: 100 * time.Millisecond, - FinalityDepth: 2, - BackfillBatchSize: 3, - RpcBatchSize: 2, - KeepFinalizedBlocksDepth: 1000, - } - ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts) - - txm, err := txmgr.NewTxm( - db, - evmConfig, - evmConfig.GasEstimator(), - evmConfig.Transactions(), - nil, - dbConfig, - dbConfig.Listener(), - ethClient, - lggr, - lp, - keyStore, - estimator) - require.NoError(t, err) - - cfg := configtest.NewGeneralConfig(t, nil) - return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) -} - func Test_HeadReporterService(t *testing.T) { t.Run("report everything", func(t *testing.T) { db := pgtest.NewSqlxDB(t) - headReporter := mocks.NewHeadReporter(t) - service := headreporter.NewHeadReporterServiceWithReporters(db, newLegacyChainContainer(t, db), logger.TestLogger(t), []headreporter.HeadReporter{headReporter}, time.Second) + headReporter := NewMockHeadReporter(t) + service := NewHeadReporterService(db, logger.TestLogger(t), headReporter) + service.reportPeriod = time.Second err := service.Start(testutils.Context(t)) require.NoError(t, err) var reportCalls atomic.Int32 - head := newHead() + head := NewHead() headReporter.On("ReportNewHead", mock.Anything, &head).Run(func(args mock.Arguments) { reportCalls.Add(1) }).Return(nil) diff --git a/core/services/headreporter/helper_test.go b/core/services/headreporter/helper_test.go new file mode 100644 index 00000000000..fa05182a851 --- /dev/null +++ b/core/services/headreporter/helper_test.go @@ -0,0 +1,5 @@ +package headreporter + +func (p *prometheusReporter) SetBackend(b PrometheusBackend) { + p.backend = b +} diff --git a/core/services/headreporter/mock_head_reporter_test.go b/core/services/headreporter/mock_head_reporter_test.go new file mode 100644 index 00000000000..21978abb86a --- /dev/null +++ b/core/services/headreporter/mock_head_reporter_test.go @@ -0,0 +1,130 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package headreporter + +import ( + context "context" + + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + mock "github.com/stretchr/testify/mock" +) + +// MockHeadReporter is an autogenerated mock type for the HeadReporter type +type MockHeadReporter struct { + mock.Mock +} + +type MockHeadReporter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockHeadReporter) EXPECT() *MockHeadReporter_Expecter { + return &MockHeadReporter_Expecter{mock: &_m.Mock} +} + +// ReportNewHead provides a mock function with given fields: ctx, head +func (_m *MockHeadReporter) ReportNewHead(ctx context.Context, head *types.Head) error { + ret := _m.Called(ctx, head) + + if len(ret) == 0 { + panic("no return value specified for ReportNewHead") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *types.Head) error); ok { + r0 = rf(ctx, head) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockHeadReporter_ReportNewHead_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportNewHead' +type MockHeadReporter_ReportNewHead_Call struct { + *mock.Call +} + +// ReportNewHead is a helper method to define mock.On call +// - ctx context.Context +// - head *types.Head +func (_e *MockHeadReporter_Expecter) ReportNewHead(ctx interface{}, head interface{}) *MockHeadReporter_ReportNewHead_Call { + return &MockHeadReporter_ReportNewHead_Call{Call: _e.mock.On("ReportNewHead", ctx, head)} +} + +func (_c *MockHeadReporter_ReportNewHead_Call) Run(run func(ctx context.Context, head *types.Head)) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*types.Head)) + }) + return _c +} + +func (_c *MockHeadReporter_ReportNewHead_Call) Return(_a0 error) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockHeadReporter_ReportNewHead_Call) RunAndReturn(run func(context.Context, *types.Head) error) *MockHeadReporter_ReportNewHead_Call { + _c.Call.Return(run) + return _c +} + +// ReportPeriodic provides a mock function with given fields: ctx +func (_m *MockHeadReporter) ReportPeriodic(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ReportPeriodic") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockHeadReporter_ReportPeriodic_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReportPeriodic' +type MockHeadReporter_ReportPeriodic_Call struct { + *mock.Call +} + +// ReportPeriodic is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockHeadReporter_Expecter) ReportPeriodic(ctx interface{}) *MockHeadReporter_ReportPeriodic_Call { + return &MockHeadReporter_ReportPeriodic_Call{Call: _e.mock.On("ReportPeriodic", ctx)} +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) Run(run func(ctx context.Context)) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) Return(_a0 error) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockHeadReporter_ReportPeriodic_Call) RunAndReturn(run func(context.Context) error) *MockHeadReporter_ReportPeriodic_Call { + _c.Call.Return(run) + return _c +} + +// NewMockHeadReporter creates a new instance of MockHeadReporter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockHeadReporter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockHeadReporter { + mock := &MockHeadReporter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/headreporter/mock_prometheus_backend_test.go b/core/services/headreporter/mock_prometheus_backend_test.go new file mode 100644 index 00000000000..ca83f6c4fbb --- /dev/null +++ b/core/services/headreporter/mock_prometheus_backend_test.go @@ -0,0 +1,204 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package headreporter + +import ( + big "math/big" + + mock "github.com/stretchr/testify/mock" +) + +// MockPrometheusBackend is an autogenerated mock type for the PrometheusBackend type +type MockPrometheusBackend struct { + mock.Mock +} + +type MockPrometheusBackend_Expecter struct { + mock *mock.Mock +} + +func (_m *MockPrometheusBackend) EXPECT() *MockPrometheusBackend_Expecter { + return &MockPrometheusBackend_Expecter{mock: &_m.Mock} +} + +// SetMaxUnconfirmedAge provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetMaxUnconfirmedAge(_a0 *big.Int, _a1 float64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetMaxUnconfirmedAge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedAge' +type MockPrometheusBackend_SetMaxUnconfirmedAge_Call struct { + *mock.Call +} + +// SetMaxUnconfirmedAge is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 float64 +func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedAge(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + return &MockPrometheusBackend_SetMaxUnconfirmedAge_Call{Call: _e.mock.On("SetMaxUnconfirmedAge", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Run(run func(_a0 *big.Int, _a1 float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(float64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedAge_Call) RunAndReturn(run func(*big.Int, float64)) *MockPrometheusBackend_SetMaxUnconfirmedAge_Call { + _c.Call.Return(run) + return _c +} + +// SetMaxUnconfirmedBlocks provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetMaxUnconfirmedBlocks(_a0 *big.Int, _a1 int64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMaxUnconfirmedBlocks' +type MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call struct { + *mock.Call +} + +// SetMaxUnconfirmedBlocks is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 int64 +func (_e *MockPrometheusBackend_Expecter) SetMaxUnconfirmedBlocks(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + return &MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call{Call: _e.mock.On("SetMaxUnconfirmedBlocks", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) Return() *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetMaxUnconfirmedBlocks_Call { + _c.Call.Return(run) + return _c +} + +// SetPipelineRunsQueued provides a mock function with given fields: n +func (_m *MockPrometheusBackend) SetPipelineRunsQueued(n int) { + _m.Called(n) +} + +// MockPrometheusBackend_SetPipelineRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineRunsQueued' +type MockPrometheusBackend_SetPipelineRunsQueued_Call struct { + *mock.Call +} + +// SetPipelineRunsQueued is a helper method to define mock.On call +// - n int +func (_e *MockPrometheusBackend_Expecter) SetPipelineRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + return &MockPrometheusBackend_SetPipelineRunsQueued_Call{Call: _e.mock.On("SetPipelineRunsQueued", n)} +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineRunsQueued_Call { + _c.Call.Return(run) + return _c +} + +// SetPipelineTaskRunsQueued provides a mock function with given fields: n +func (_m *MockPrometheusBackend) SetPipelineTaskRunsQueued(n int) { + _m.Called(n) +} + +// MockPrometheusBackend_SetPipelineTaskRunsQueued_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPipelineTaskRunsQueued' +type MockPrometheusBackend_SetPipelineTaskRunsQueued_Call struct { + *mock.Call +} + +// SetPipelineTaskRunsQueued is a helper method to define mock.On call +// - n int +func (_e *MockPrometheusBackend_Expecter) SetPipelineTaskRunsQueued(n interface{}) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + return &MockPrometheusBackend_SetPipelineTaskRunsQueued_Call{Call: _e.mock.On("SetPipelineTaskRunsQueued", n)} +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Run(run func(n int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) Return() *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call) RunAndReturn(run func(int)) *MockPrometheusBackend_SetPipelineTaskRunsQueued_Call { + _c.Call.Return(run) + return _c +} + +// SetUnconfirmedTransactions provides a mock function with given fields: _a0, _a1 +func (_m *MockPrometheusBackend) SetUnconfirmedTransactions(_a0 *big.Int, _a1 int64) { + _m.Called(_a0, _a1) +} + +// MockPrometheusBackend_SetUnconfirmedTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetUnconfirmedTransactions' +type MockPrometheusBackend_SetUnconfirmedTransactions_Call struct { + *mock.Call +} + +// SetUnconfirmedTransactions is a helper method to define mock.On call +// - _a0 *big.Int +// - _a1 int64 +func (_e *MockPrometheusBackend_Expecter) SetUnconfirmedTransactions(_a0 interface{}, _a1 interface{}) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + return &MockPrometheusBackend_SetUnconfirmedTransactions_Call{Call: _e.mock.On("SetUnconfirmedTransactions", _a0, _a1)} +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Run(run func(_a0 *big.Int, _a1 int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int64)) + }) + return _c +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) Return() *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Return() + return _c +} + +func (_c *MockPrometheusBackend_SetUnconfirmedTransactions_Call) RunAndReturn(run func(*big.Int, int64)) *MockPrometheusBackend_SetUnconfirmedTransactions_Call { + _c.Call.Return(run) + return _c +} + +// NewMockPrometheusBackend creates a new instance of MockPrometheusBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockPrometheusBackend(t interface { + mock.TestingT + Cleanup(func()) +}) *MockPrometheusBackend { + mock := &MockPrometheusBackend{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/headreporter/prometheus_reporter_test.go b/core/services/headreporter/prometheus_reporter_test.go index 131805cd7a5..eeff408ed71 100644 --- a/core/services/headreporter/prometheus_reporter_test.go +++ b/core/services/headreporter/prometheus_reporter_test.go @@ -1,33 +1,42 @@ -package headreporter_test +package headreporter import ( "math/big" "testing" + "time" + "github.com/jmoiron/sqlx" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" ) func Test_PrometheusReporter(t *testing.T) { t.Run("with nothing in the database", func(t *testing.T) { db := pgtest.NewSqlxDB(t) - backend := mocks.NewPrometheusBackend(t) - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) - + backend := NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - head := newHead() + reporter := NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) + + head := NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -48,16 +57,17 @@ func Test_PrometheusReporter(t *testing.T) { cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7)) - backend := mocks.NewPrometheusBackend(t) + backend := NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(3)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), mock.MatchedBy(func(s float64) bool { return s > 0 })).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(35)).Return() - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) + reporter := NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) - head := newHead() + head := NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -76,14 +86,15 @@ func Test_PrometheusReporter(t *testing.T) { cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 2) - backend := mocks.NewPrometheusBackend(t) + backend := NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend) + reporter := NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter.SetBackend(backend) - head := newHead() + head := NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -94,3 +105,39 @@ func Test_PrometheusReporter(t *testing.T) { require.NoError(t, err) }) } + +func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { + config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) + keyStore := cltest.NewKeyStore(t, db).Eth() + ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) + require.NoError(t, err) + lggr := logger.TestLogger(t) + lpOpts := logpoller.Opts{ + PollPeriod: 100 * time.Millisecond, + FinalityDepth: 2, + BackfillBatchSize: 3, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 1000, + } + ht := headtracker.NewSimulatedHeadTracker(ethClient, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, ht, lpOpts) + + txm, err := txmgr.NewTxm( + db, + evmConfig, + evmConfig.GasEstimator(), + evmConfig.Transactions(), + nil, + dbConfig, + dbConfig.Listener(), + ethClient, + lggr, + lp, + keyStore, + estimator) + require.NoError(t, err) + + cfg := configtest.NewGeneralConfig(t, nil) + return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) +} diff --git a/core/services/telemetry/common.go b/core/services/telemetry/common.go index 1ccd9674589..37a92f16c6d 100644 --- a/core/services/telemetry/common.go +++ b/core/services/telemetry/common.go @@ -6,7 +6,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" ) -//go:generate mockery --quiet --name MonitoringEndpointGenerator --output ./mocks --case=underscore type MonitoringEndpointGenerator interface { GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) ocrtypes.MonitoringEndpoint } diff --git a/core/services/telemetry/mocks/monitoring_endpoint_generator.go b/core/services/telemetry/mocks/monitoring_endpoint_generator.go deleted file mode 100644 index 717654f404f..00000000000 --- a/core/services/telemetry/mocks/monitoring_endpoint_generator.go +++ /dev/null @@ -1,49 +0,0 @@ -// Code generated by mockery v2.43.2. DO NOT EDIT. - -package mocks - -import ( - commontypes "github.com/smartcontractkit/libocr/commontypes" - mock "github.com/stretchr/testify/mock" - - synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" -) - -// MonitoringEndpointGenerator is an autogenerated mock type for the MonitoringEndpointGenerator type -type MonitoringEndpointGenerator struct { - mock.Mock -} - -// GenMonitoringEndpoint provides a mock function with given fields: network, chainID, contractID, telemType -func (_m *MonitoringEndpointGenerator) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { - ret := _m.Called(network, chainID, contractID, telemType) - - if len(ret) == 0 { - panic("no return value specified for GenMonitoringEndpoint") - } - - var r0 commontypes.MonitoringEndpoint - if rf, ok := ret.Get(0).(func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint); ok { - r0 = rf(network, chainID, contractID, telemType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(commontypes.MonitoringEndpoint) - } - } - - return r0 -} - -// NewMonitoringEndpointGenerator creates a new instance of MonitoringEndpointGenerator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMonitoringEndpointGenerator(t interface { - mock.TestingT - Cleanup(func()) -}) *MonitoringEndpointGenerator { - mock := &MonitoringEndpointGenerator{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} From c52017238f50071febba79cae66af580c1e7ace7 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Tue, 6 Aug 2024 19:16:12 +0100 Subject: [PATCH 11/21] head telemetry enabled by default --- core/config/docs/core.toml | 2 +- core/services/chainlink/config_general_test.go | 2 +- core/services/chainlink/config_head_report_test.go | 2 +- core/services/chainlink/config_test.go | 4 ++-- core/services/chainlink/testdata/config-empty-effective.toml | 2 +- core/services/chainlink/testdata/config-full.toml | 2 +- .../chainlink/testdata/config-multi-chain-effective.toml | 2 +- core/web/resolver/testdata/config-empty-effective.toml | 2 +- core/web/resolver/testdata/config-full.toml | 2 +- core/web/resolver/testdata/config-multi-chain-effective.toml | 2 +- docs/CONFIG.md | 4 ++-- testdata/scripts/node/validate/default.txtar | 2 +- .../scripts/node/validate/disk-based-logging-disabled.txtar | 2 +- .../scripts/node/validate/disk-based-logging-no-dir.txtar | 2 +- testdata/scripts/node/validate/disk-based-logging.txtar | 2 +- testdata/scripts/node/validate/invalid-ocr-p2p.txtar | 2 +- testdata/scripts/node/validate/invalid.txtar | 2 +- testdata/scripts/node/validate/valid.txtar | 2 +- testdata/scripts/node/validate/warnings.txtar | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index e45a7cd3841..d21863178c8 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -654,4 +654,4 @@ TransmitTimeout = "5s" # Default [HeadReport] # TelemetryEnabled controls if it collects information about new blocks from blockchain -TelemetryEnabled = false # Default +TelemetryEnabled = true # Default diff --git a/core/services/chainlink/config_general_test.go b/core/services/chainlink/config_general_test.go index 6247ebd91c8..0f9839a1011 100644 --- a/core/services/chainlink/config_general_test.go +++ b/core/services/chainlink/config_general_test.go @@ -30,7 +30,7 @@ func TestTOMLGeneralConfig_Defaults(t *testing.T) { assert.False(t, config.StarkNetEnabled()) assert.Equal(t, false, config.JobPipeline().ExternalInitiatorsEnabled()) assert.Equal(t, 15*time.Minute, config.WebServer().SessionTimeout().Duration()) - assert.Equal(t, false, config.HeadReport().TelemetryEnabled()) + assert.Equal(t, true, config.HeadReport().TelemetryEnabled()) } func TestTOMLGeneralConfig_InsecureConfig(t *testing.T) { diff --git a/core/services/chainlink/config_head_report_test.go b/core/services/chainlink/config_head_report_test.go index 1840c4f578b..a7b9e51cddd 100644 --- a/core/services/chainlink/config_head_report_test.go +++ b/core/services/chainlink/config_head_report_test.go @@ -14,5 +14,5 @@ func TestHeadReportConfig(t *testing.T) { require.NoError(t, err) hr := cfg.HeadReport() - require.True(t, hr.TelemetryEnabled()) + require.False(t, hr.TelemetryEnabled()) } diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index bd75e92b23b..245f0b183a6 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -734,7 +734,7 @@ func TestConfig_Marshal(t *testing.T) { VerboseLogging: ptr(true), } full.HeadReport = toml.HeadReport{ - TelemetryEnabled: ptr(true), + TelemetryEnabled: ptr(false), } for _, tt := range []struct { name string @@ -1208,7 +1208,7 @@ TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' `}, {"HeadReport", Config{Core: toml.Core{HeadReport: full.HeadReport}}, `[HeadReport] -TelemetryEnabled = true +TelemetryEnabled = false `}, {"full", full, fullTOML}, {"multi-chain", multiChain, multiChainTOML}, diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index 93a5e509ab1..bc60187fb83 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -238,7 +238,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index b2c342f33c7..5b1b16eaac2 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -248,7 +248,7 @@ TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' [HeadReport] -TelemetryEnabled = true +TelemetryEnabled = false [Capabilities] [Capabilities.Peering] diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index f97e31f5b7d..1f879a6a1c8 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -238,7 +238,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index 93a5e509ab1..bc60187fb83 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -238,7 +238,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index ab6d0ab8447..04a66e28b7c 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -248,7 +248,7 @@ TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' [HeadReport] -TelemetryEnabled = true +TelemetryEnabled = false [Capabilities] [Capabilities.Peering] diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 5bf08c78346..9894aa95ae9 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -238,7 +238,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/docs/CONFIG.md b/docs/CONFIG.md index c2270599d00..83bc9d59df1 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1771,13 +1771,13 @@ the transmission to be failed. ## HeadReport ```toml [HeadReport] -TelemetryEnabled = false # Default +TelemetryEnabled = true # Default ``` ### TelemetryEnabled ```toml -TelemetryEnabled = false # Default +TelemetryEnabled = true # Default ``` TelemetryEnabled controls if it collects information about new blocks from blockchain diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index 10897c897c7..f230a407c50 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -250,7 +250,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index c25e5662daf..01eccbf327f 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -294,7 +294,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 9b7410df901..6a1e701b762 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -294,7 +294,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 302700174b5..582f246c15f 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -294,7 +294,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 6fa9ca932a8..8901d4848ca 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -279,7 +279,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index 99410d91078..bc6e8dd848c 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -284,7 +284,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index d11377ec74a..c3d734e2661 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -291,7 +291,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index 9d27734d058..bc2900e1a91 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -273,7 +273,7 @@ TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' [HeadReport] -TelemetryEnabled = false +TelemetryEnabled = true [Capabilities] [Capabilities.Peering] From 2f6cc9d6a5ffb64b7fa9bf36c945395cfcf668d9 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Wed, 7 Aug 2024 10:56:34 +0100 Subject: [PATCH 12/21] review --- .mockery.yaml | 19 +++- common/types/mocks/monitoring_endpoint.go | 65 ++++++++++++++ ...reporter_test.go => head_reporter_mock.go} | 3 +- ...end_test.go => prometheus_backend_mock.go} | 0 .../headreporter/prometheus_reporter_test.go | 33 ++++--- .../headreporter/telemetry_reporter.go | 8 +- .../headreporter/telemetry_reporter_test.go | 60 ++++--------- .../monitoring_endpoint_generator_mock.go | 88 +++++++++++++++++++ testdata/scripts/health/default.txtar | 2 +- testdata/scripts/health/multi-chain.txtar | 2 +- 10 files changed, 213 insertions(+), 67 deletions(-) create mode 100644 common/types/mocks/monitoring_endpoint.go rename core/services/headreporter/{mock_head_reporter_test.go => head_reporter_mock.go} (99%) rename core/services/headreporter/{mock_prometheus_backend_test.go => prometheus_backend_mock.go} (100%) create mode 100644 core/services/telemetry/monitoring_endpoint_generator_mock.go diff --git a/.mockery.yaml b/.mockery.yaml index 7b15985b3ae..fc134ef95b0 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -265,12 +265,20 @@ packages: github.com/smartcontractkit/chainlink/v2/core/services/headreporter: config: dir: "{{ .InterfaceDir }}" - filename: "mock_{{ .InterfaceName | snakecase }}_test.go" + filename: "{{ .InterfaceName | snakecase }}_mock.go" inpackage: true mockname: "Mock{{ .InterfaceName | camelcase }}" interfaces: HeadReporter: PrometheusBackend: + github.com/smartcontractkit/libocr/commontypes: + config: + dir: "common/types/mocks" +# filename: "{{ .InterfaceName | snakecase }}.go" +# inpackage: true + mockname: "Mock{{ .InterfaceName | camelcase }}" + interfaces: + MonitoringEndpoint: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm: interfaces: BatchCaller: @@ -305,6 +313,15 @@ packages: interfaces: Config: FeeConfig: + github.com/smartcontractkit/chainlink/v2/core/services/telemetry: + config: + dir: "{{ .InterfaceDir }}" + filename: "{{ .InterfaceName | snakecase }}_mock.go" + inpackage: true + mockname: "Mock{{ .InterfaceName | camelcase }}" + interfaces: + MonitoringEndpointGenerator: + IngressAgent: github.com/smartcontractkit/chainlink/v2/core/services/webhook: interfaces: ExternalInitiatorManager: diff --git a/common/types/mocks/monitoring_endpoint.go b/common/types/mocks/monitoring_endpoint.go new file mode 100644 index 00000000000..c5a2fbdaae5 --- /dev/null +++ b/common/types/mocks/monitoring_endpoint.go @@ -0,0 +1,65 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// MockMonitoringEndpoint is an autogenerated mock type for the MonitoringEndpoint type +type MockMonitoringEndpoint struct { + mock.Mock +} + +type MockMonitoringEndpoint_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMonitoringEndpoint) EXPECT() *MockMonitoringEndpoint_Expecter { + return &MockMonitoringEndpoint_Expecter{mock: &_m.Mock} +} + +// SendLog provides a mock function with given fields: log +func (_m *MockMonitoringEndpoint) SendLog(log []byte) { + _m.Called(log) +} + +// MockMonitoringEndpoint_SendLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendLog' +type MockMonitoringEndpoint_SendLog_Call struct { + *mock.Call +} + +// SendLog is a helper method to define mock.On call +// - log []byte +func (_e *MockMonitoringEndpoint_Expecter) SendLog(log interface{}) *MockMonitoringEndpoint_SendLog_Call { + return &MockMonitoringEndpoint_SendLog_Call{Call: _e.mock.On("SendLog", log)} +} + +func (_c *MockMonitoringEndpoint_SendLog_Call) Run(run func(log []byte)) *MockMonitoringEndpoint_SendLog_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MockMonitoringEndpoint_SendLog_Call) Return() *MockMonitoringEndpoint_SendLog_Call { + _c.Call.Return() + return _c +} + +func (_c *MockMonitoringEndpoint_SendLog_Call) RunAndReturn(run func([]byte)) *MockMonitoringEndpoint_SendLog_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMonitoringEndpoint creates a new instance of MockMonitoringEndpoint. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockMonitoringEndpoint(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMonitoringEndpoint { + mock := &MockMonitoringEndpoint{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/headreporter/mock_head_reporter_test.go b/core/services/headreporter/head_reporter_mock.go similarity index 99% rename from core/services/headreporter/mock_head_reporter_test.go rename to core/services/headreporter/head_reporter_mock.go index 21978abb86a..9021c7f8a2d 100644 --- a/core/services/headreporter/mock_head_reporter_test.go +++ b/core/services/headreporter/head_reporter_mock.go @@ -5,8 +5,9 @@ package headreporter import ( context "context" - types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" mock "github.com/stretchr/testify/mock" + + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) // MockHeadReporter is an autogenerated mock type for the HeadReporter type diff --git a/core/services/headreporter/mock_prometheus_backend_test.go b/core/services/headreporter/prometheus_backend_mock.go similarity index 100% rename from core/services/headreporter/mock_prometheus_backend_test.go rename to core/services/headreporter/prometheus_backend_mock.go diff --git a/core/services/headreporter/prometheus_reporter_test.go b/core/services/headreporter/prometheus_reporter_test.go index eeff408ed71..32d2c09d0ec 100644 --- a/core/services/headreporter/prometheus_reporter_test.go +++ b/core/services/headreporter/prometheus_reporter_test.go @@ -1,4 +1,4 @@ -package headreporter +package headreporter_test import ( "math/big" @@ -6,37 +6,36 @@ import ( "time" "github.com/jmoiron/sqlx" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" ) func Test_PrometheusReporter(t *testing.T) { t.Run("with nothing in the database", func(t *testing.T) { db := pgtest.NewSqlxDB(t) - backend := NewMockPrometheusBackend(t) + backend := headreporter.NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - reporter := NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) reporter.SetBackend(backend) - head := NewHead() + head := headreporter.NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -57,17 +56,17 @@ func Test_PrometheusReporter(t *testing.T) { cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) require.NoError(t, txStore.UpdateTxAttemptBroadcastBeforeBlockNum(testutils.Context(t), etx.ID, 7)) - backend := NewMockPrometheusBackend(t) + backend := headreporter.NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(3)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), mock.MatchedBy(func(s float64) bool { return s > 0 })).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(35)).Return() - reporter := NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) reporter.SetBackend(backend) - head := NewHead() + head := headreporter.NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) @@ -86,15 +85,15 @@ func Test_PrometheusReporter(t *testing.T) { cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 2) - backend := NewMockPrometheusBackend(t) + backend := headreporter.NewMockPrometheusBackend(t) backend.On("SetUnconfirmedTransactions", big.NewInt(0), int64(0)).Return() backend.On("SetMaxUnconfirmedAge", big.NewInt(0), float64(0)).Return() backend.On("SetMaxUnconfirmedBlocks", big.NewInt(0), int64(0)).Return() - reporter := NewPrometheusReporter(db, newLegacyChainContainer(t, db)) + reporter := headreporter.NewPrometheusReporter(db, newLegacyChainContainer(t, db)) reporter.SetBackend(backend) - head := NewHead() + head := headreporter.NewHead() err := reporter.ReportNewHead(testutils.Context(t), &head) require.NoError(t, err) diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go index e3d8e096084..eb7f1ae143d 100644 --- a/core/services/headreporter/telemetry_reporter.go +++ b/core/services/headreporter/telemetry_reporter.go @@ -15,11 +15,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" ) -type ( - telemetryReporter struct { - endpoints map[uint64]commontypes.MonitoringEndpoint - } -) +type telemetryReporter struct { + endpoints map[uint64]commontypes.MonitoringEndpoint +} func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { endpoints := make(map[uint64]commontypes.MonitoringEndpoint) diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go index 145a6329e80..7f284f3fcc8 100644 --- a/core/services/headreporter/telemetry_reporter_test.go +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -7,9 +7,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "google.golang.org/protobuf/proto" + mocks2 "github.com/smartcontractkit/chainlink/v2/common/types/mocks" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" @@ -18,43 +18,15 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" - mocks2 "github.com/smartcontractkit/chainlink/v2/core/services/telemetry/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" ) -type IngressAgent struct { - mock.Mock -} - -func (t *IngressAgent) SendLog(telemetry []byte) { - _ = t.Called(telemetry) -} - -func NewIngressAgent(t interface { - mock.TestingT - Cleanup(func()) -}) *IngressAgent { - m := &IngressAgent{} - m.Mock.Test(t) - - t.Cleanup(func() { m.AssertExpectations(t) }) - - return m -} - func Test_TelemetryReporter_NewHead(t *testing.T) { chain := mocks.NewChain(t) chain.On("ID").Return(big.NewInt(100)) chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) - ingressAgent := NewIngressAgent(t) - - monitoringEndpointGen := mocks2.NewMonitoringEndpointGenerator(t) - monitoringEndpointGen. - On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). - Return(ingressAgent) - reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) - head := evmtypes.Head{ Number: 42, EVMChainID: ubig.NewI(100), @@ -82,7 +54,14 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { }) assert.NoError(t, err) - ingressAgent.On("SendLog", requestBytes).Return() + monitoringEndpoint := mocks2.NewMockMonitoringEndpoint(t) + monitoringEndpoint.On("SendLog", requestBytes).Return() + + monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) + monitoringEndpointGen. + On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). + Return(monitoringEndpoint) + reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) err = reporter.ReportNewHead(testutils.Context(t), &head) assert.NoError(t, err) @@ -94,14 +73,6 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) - ingressAgent := NewIngressAgent(t) - - monitoringEndpointGen := mocks2.NewMonitoringEndpointGenerator(t) - monitoringEndpointGen. - On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). - Return(ingressAgent) - reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) - head := evmtypes.Head{ Number: 42, EVMChainID: ubig.NewI(100), @@ -118,7 +89,14 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { }) assert.NoError(t, err) - ingressAgent.On("SendLog", requestBytes).Return() + monitoringEndpoint := mocks2.NewMockMonitoringEndpoint(t) + monitoringEndpoint.On("SendLog", requestBytes).Return() + + monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) + monitoringEndpointGen. + On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). + Return(monitoringEndpoint) + reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) err = reporter.ReportNewHead(testutils.Context(t), &head) assert.Errorf(t, err, "No finalized block was found for chain_id=100") @@ -130,7 +108,7 @@ func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) - monitoringEndpointGen := mocks2.NewMonitoringEndpointGenerator(t) + monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(nil) diff --git a/core/services/telemetry/monitoring_endpoint_generator_mock.go b/core/services/telemetry/monitoring_endpoint_generator_mock.go new file mode 100644 index 00000000000..a0fc503ecca --- /dev/null +++ b/core/services/telemetry/monitoring_endpoint_generator_mock.go @@ -0,0 +1,88 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package telemetry + +import ( + commontypes "github.com/smartcontractkit/libocr/commontypes" + mock "github.com/stretchr/testify/mock" + + synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" +) + +// MockMonitoringEndpointGenerator is an autogenerated mock type for the MonitoringEndpointGenerator type +type MockMonitoringEndpointGenerator struct { + mock.Mock +} + +type MockMonitoringEndpointGenerator_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMonitoringEndpointGenerator) EXPECT() *MockMonitoringEndpointGenerator_Expecter { + return &MockMonitoringEndpointGenerator_Expecter{mock: &_m.Mock} +} + +// GenMonitoringEndpoint provides a mock function with given fields: network, chainID, contractID, telemType +func (_m *MockMonitoringEndpointGenerator) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { + ret := _m.Called(network, chainID, contractID, telemType) + + if len(ret) == 0 { + panic("no return value specified for GenMonitoringEndpoint") + } + + var r0 commontypes.MonitoringEndpoint + if rf, ok := ret.Get(0).(func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint); ok { + r0 = rf(network, chainID, contractID, telemType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(commontypes.MonitoringEndpoint) + } + } + + return r0 +} + +// MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenMonitoringEndpoint' +type MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call struct { + *mock.Call +} + +// GenMonitoringEndpoint is a helper method to define mock.On call +// - network string +// - chainID string +// - contractID string +// - telemType synchronization.TelemetryType +func (_e *MockMonitoringEndpointGenerator_Expecter) GenMonitoringEndpoint(network interface{}, chainID interface{}, contractID interface{}, telemType interface{}) *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + return &MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call{Call: _e.mock.On("GenMonitoringEndpoint", network, chainID, contractID, telemType)} +} + +func (_c *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call) Run(run func(network string, chainID string, contractID string, telemType synchronization.TelemetryType)) *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(string), args[3].(synchronization.TelemetryType)) + }) + return _c +} + +func (_c *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call) Return(_a0 commontypes.MonitoringEndpoint) *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call) RunAndReturn(run func(string, string, string, synchronization.TelemetryType) commontypes.MonitoringEndpoint) *MockMonitoringEndpointGenerator_GenMonitoringEndpoint_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMonitoringEndpointGenerator creates a new instance of MockMonitoringEndpointGenerator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockMonitoringEndpointGenerator(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMonitoringEndpointGenerator { + mock := &MockMonitoringEndpointGenerator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/testdata/scripts/health/default.txtar b/testdata/scripts/health/default.txtar index 55ce9aaa2f0..97c41553674 100644 --- a/testdata/scripts/health/default.txtar +++ b/testdata/scripts/health/default.txtar @@ -31,7 +31,7 @@ fj293fbBnlQ!f9vNs HTTPPort = $PORT -- out.txt -- -ok HeadReporterService +ok HeadReporter ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool diff --git a/testdata/scripts/health/multi-chain.txtar b/testdata/scripts/health/multi-chain.txtar index b9410b3898e..d0ab9320d5b 100644 --- a/testdata/scripts/health/multi-chain.txtar +++ b/testdata/scripts/health/multi-chain.txtar @@ -84,7 +84,7 @@ ok EVM.1.Txm.Broadcaster ok EVM.1.Txm.Confirmer ok EVM.1.Txm.Finalizer ok EVM.1.Txm.WrappedEvmEstimator -ok HeadReporterService +ok HeadReporter ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool From 7d6e2ed9f6bdfb64b5919beaa82302dc5a3d7179 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Wed, 7 Aug 2024 11:15:26 +0100 Subject: [PATCH 13/21] rebase --- core/services/headreporter/prometheus_reporter_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/services/headreporter/prometheus_reporter_test.go b/core/services/headreporter/prometheus_reporter_test.go index 32d2c09d0ec..d96e617fd79 100644 --- a/core/services/headreporter/prometheus_reporter_test.go +++ b/core/services/headreporter/prometheus_reporter_test.go @@ -134,7 +134,8 @@ func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainCon lggr, lp, keyStore, - estimator) + estimator, + ht) require.NoError(t, err) cfg := configtest.NewGeneralConfig(t, nil) From 562773a8b4d1e0723f237a6d9b2642134c663632 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Wed, 7 Aug 2024 12:03:12 +0100 Subject: [PATCH 14/21] review --- core/services/headreporter/head_reporter_mock.go | 3 +-- core/web/testdata/body/health.html | 2 +- core/web/testdata/body/health.json | 4 ++-- core/web/testdata/body/health.txt | 2 +- testdata/scripts/health/default.txtar | 4 ++-- testdata/scripts/health/multi-chain.txtar | 4 ++-- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/core/services/headreporter/head_reporter_mock.go b/core/services/headreporter/head_reporter_mock.go index 9021c7f8a2d..21978abb86a 100644 --- a/core/services/headreporter/head_reporter_mock.go +++ b/core/services/headreporter/head_reporter_mock.go @@ -5,9 +5,8 @@ package headreporter import ( context "context" - mock "github.com/stretchr/testify/mock" - types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + mock "github.com/stretchr/testify/mock" ) // MockHeadReporter is an autogenerated mock type for the HeadReporter type diff --git a/core/web/testdata/body/health.html b/core/web/testdata/body/health.html index 1b93dfec43c..d2b6db906b4 100644 --- a/core/web/testdata/body/health.html +++ b/core/web/testdata/body/health.html @@ -73,7 +73,7 @@
- HeadReporterService + HeadReporter
JobSpawner diff --git a/core/web/testdata/body/health.json b/core/web/testdata/body/health.json index 7f5f6bc2f95..81ed7ff6d11 100644 --- a/core/web/testdata/body/health.json +++ b/core/web/testdata/body/health.json @@ -110,9 +110,9 @@ }, { "type": "checks", - "id": "HeadReporterService", + "id": "HeadReporter", "attributes": { - "name": "HeadReporterService", + "name": "HeadReporter", "status": "passing", "output": "" } diff --git a/core/web/testdata/body/health.txt b/core/web/testdata/body/health.txt index 876bc631a40..6b165d26d99 100644 --- a/core/web/testdata/body/health.txt +++ b/core/web/testdata/body/health.txt @@ -11,7 +11,7 @@ ok EVM.0.Txm.Broadcaster ok EVM.0.Txm.Confirmer ok EVM.0.Txm.Finalizer ok EVM.0.Txm.WrappedEvmEstimator -ok HeadReporterService +ok HeadReporter ok JobSpawner ok Mailbox.Monitor ok Mercury.WSRPCPool diff --git a/testdata/scripts/health/default.txtar b/testdata/scripts/health/default.txtar index 97c41553674..777d3e5e126 100644 --- a/testdata/scripts/health/default.txtar +++ b/testdata/scripts/health/default.txtar @@ -46,9 +46,9 @@ ok TelemetryManager "data": [ { "type": "checks", - "id": "HeadReporterService", + "id": "HeadReporter", "attributes": { - "name": "HeadReporterService", + "name": "HeadReporter", "status": "passing", "output": "" } diff --git a/testdata/scripts/health/multi-chain.txtar b/testdata/scripts/health/multi-chain.txtar index d0ab9320d5b..bba3b3e111f 100644 --- a/testdata/scripts/health/multi-chain.txtar +++ b/testdata/scripts/health/multi-chain.txtar @@ -240,9 +240,9 @@ ok TelemetryManager }, { "type": "checks", - "id": "HeadReporterService", + "id": "HeadReporter", "attributes": { - "name": "HeadReporterService", + "name": "HeadReporter", "status": "passing", "output": "" } From 3a31ee6628cf438217579b51d6ec647ade6019e1 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Wed, 7 Aug 2024 18:00:19 +0100 Subject: [PATCH 15/21] drop config --- core/config/app_config.go | 1 - core/config/docs/core.toml | 4 -- core/config/head_report_config.go | 5 -- core/config/toml/types.go | 12 ----- core/services/chainlink/application.go | 9 +--- core/services/chainlink/config_general.go | 6 --- .../services/chainlink/config_general_test.go | 1 - core/services/chainlink/config_head_report.go | 13 ----- .../chainlink/config_head_report_test.go | 18 ------- core/services/chainlink/config_test.go | 6 --- .../chainlink/mocks/general_config.go | 47 ------------------- .../testdata/config-empty-effective.toml | 3 -- .../chainlink/testdata/config-full.toml | 3 -- .../config-multi-chain-effective.toml | 3 -- .../testdata/config-empty-effective.toml | 3 -- core/web/resolver/testdata/config-full.toml | 3 -- .../config-multi-chain-effective.toml | 3 -- docs/CONFIG.md | 13 ----- testdata/scripts/node/validate/default.txtar | 3 -- .../disk-based-logging-disabled.txtar | 3 -- .../validate/disk-based-logging-no-dir.txtar | 3 -- .../node/validate/disk-based-logging.txtar | 3 -- .../node/validate/invalid-ocr-p2p.txtar | 3 -- testdata/scripts/node/validate/invalid.txtar | 3 -- testdata/scripts/node/validate/valid.txtar | 3 -- testdata/scripts/node/validate/warnings.txtar | 3 -- 26 files changed, 2 insertions(+), 175 deletions(-) delete mode 100644 core/config/head_report_config.go delete mode 100644 core/services/chainlink/config_head_report.go delete mode 100644 core/services/chainlink/config_head_report_test.go diff --git a/core/config/app_config.go b/core/config/app_config.go index fe877d110ab..112e242636f 100644 --- a/core/config/app_config.go +++ b/core/config/app_config.go @@ -53,7 +53,6 @@ type AppConfig interface { Pyroscope() Pyroscope Sentry() Sentry TelemetryIngress() TelemetryIngress - HeadReport() HeadReport Threshold() Threshold WebServer() WebServer Tracing() Tracing diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index d21863178c8..d0960779c6c 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -651,7 +651,3 @@ TransmitQueueMaxSize = 10_000 # Default # when sending a message to the mercury server, before aborting and considering # the transmission to be failed. TransmitTimeout = "5s" # Default - -[HeadReport] -# TelemetryEnabled controls if it collects information about new blocks from blockchain -TelemetryEnabled = true # Default diff --git a/core/config/head_report_config.go b/core/config/head_report_config.go deleted file mode 100644 index 9f4ae85eb6c..00000000000 --- a/core/config/head_report_config.go +++ /dev/null @@ -1,5 +0,0 @@ -package config - -type HeadReport interface { - TelemetryEnabled() bool -} diff --git a/core/config/toml/types.go b/core/config/toml/types.go index a503720ea9e..0c91ddd81a9 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -56,7 +56,6 @@ type Core struct { Insecure Insecure `toml:",omitempty"` Tracing Tracing `toml:",omitempty"` Mercury Mercury `toml:",omitempty"` - HeadReport HeadReport `toml:",omitempty"` Capabilities Capabilities `toml:",omitempty"` } @@ -77,7 +76,6 @@ func (c *Core) SetFrom(f *Core) { c.TelemetryIngress.setFrom(&f.TelemetryIngress) c.AuditLogger.SetFrom(&f.AuditLogger) c.Log.setFrom(&f.Log) - c.HeadReport.setFrom(&f.HeadReport) c.WebServer.setFrom(&f.WebServer) c.JobPipeline.setFrom(&f.JobPipeline) @@ -487,16 +485,6 @@ func (t *TelemetryIngress) setFrom(f *TelemetryIngress) { } } -type HeadReport struct { - TelemetryEnabled *bool -} - -func (t *HeadReport) setFrom(f *HeadReport) { - if v := f.TelemetryEnabled; v != nil { - t.TelemetryEnabled = v - } -} - type AuditLogger struct { Enabled *bool ForwardToUrl *commonconfig.URL diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 5dc12a7defc..04eaa8c6905 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -367,13 +367,8 @@ func NewApplication(opts ApplicationOpts) (Application, error) { ) promReporter := headreporter.NewPrometheusReporter(opts.DS, legacyEVMChains) - var headReporter *headreporter.HeadReporterService - if cfg.HeadReport().TelemetryEnabled() { - telemReporter := headreporter.NewTelemetryReporter(legacyEVMChains, telemetryManager) - headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) - } else { - headReporter = headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter) - } + telemReporter := headreporter.NewTelemetryReporter(legacyEVMChains, telemetryManager) + headReporter := headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) srvcs = append(srvcs, headReporter) for _, chain := range legacyEVMChains.Slice() { chain.HeadBroadcaster().Subscribe(headReporter) diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index abdd48d7592..5b6b839fb5e 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -483,12 +483,6 @@ func (g *generalConfig) RootDir() string { return h } -func (g *generalConfig) HeadReport() coreconfig.HeadReport { - return &headReport{ - h: g.c.HeadReport, - } -} - func (g *generalConfig) TelemetryIngress() coreconfig.TelemetryIngress { return &telemetryIngressConfig{ c: g.c.TelemetryIngress, diff --git a/core/services/chainlink/config_general_test.go b/core/services/chainlink/config_general_test.go index 0f9839a1011..29393ee0fdd 100644 --- a/core/services/chainlink/config_general_test.go +++ b/core/services/chainlink/config_general_test.go @@ -30,7 +30,6 @@ func TestTOMLGeneralConfig_Defaults(t *testing.T) { assert.False(t, config.StarkNetEnabled()) assert.Equal(t, false, config.JobPipeline().ExternalInitiatorsEnabled()) assert.Equal(t, 15*time.Minute, config.WebServer().SessionTimeout().Duration()) - assert.Equal(t, true, config.HeadReport().TelemetryEnabled()) } func TestTOMLGeneralConfig_InsecureConfig(t *testing.T) { diff --git a/core/services/chainlink/config_head_report.go b/core/services/chainlink/config_head_report.go deleted file mode 100644 index e6e292938d9..00000000000 --- a/core/services/chainlink/config_head_report.go +++ /dev/null @@ -1,13 +0,0 @@ -package chainlink - -import ( - "github.com/smartcontractkit/chainlink/v2/core/config/toml" -) - -type headReport struct { - h toml.HeadReport -} - -func (h headReport) TelemetryEnabled() bool { - return *h.h.TelemetryEnabled -} diff --git a/core/services/chainlink/config_head_report_test.go b/core/services/chainlink/config_head_report_test.go deleted file mode 100644 index a7b9e51cddd..00000000000 --- a/core/services/chainlink/config_head_report_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package chainlink - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestHeadReportConfig(t *testing.T) { - opts := GeneralConfigOpts{ - ConfigStrings: []string{fullTOML}, - } - cfg, err := opts.New() - require.NoError(t, err) - - hr := cfg.HeadReport() - require.False(t, hr.TelemetryEnabled()) -} diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 245f0b183a6..190175f1499 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -733,9 +733,6 @@ func TestConfig_Marshal(t *testing.T) { }, VerboseLogging: ptr(true), } - full.HeadReport = toml.HeadReport{ - TelemetryEnabled: ptr(false), - } for _, tt := range []struct { name string config Config @@ -1206,9 +1203,6 @@ CertFile = '/path/to/cert.pem' [Mercury.Transmitter] TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' -`}, - {"HeadReport", Config{Core: toml.Core{HeadReport: full.HeadReport}}, `[HeadReport] -TelemetryEnabled = false `}, {"full", full, fullTOML}, {"multi-chain", multiChain, multiChainTOML}, diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index f04ff40c566..c42ed5c7014 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -692,53 +692,6 @@ func (_c *GeneralConfig_FluxMonitor_Call) RunAndReturn(run func() config.FluxMon return _c } -// HeadReport provides a mock function with given fields: -func (_m *GeneralConfig) HeadReport() config.HeadReport { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for HeadReport") - } - - var r0 config.HeadReport - if rf, ok := ret.Get(0).(func() config.HeadReport); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(config.HeadReport) - } - } - - return r0 -} - -// GeneralConfig_HeadReport_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HeadReport' -type GeneralConfig_HeadReport_Call struct { - *mock.Call -} - -// HeadReport is a helper method to define mock.On call -func (_e *GeneralConfig_Expecter) HeadReport() *GeneralConfig_HeadReport_Call { - return &GeneralConfig_HeadReport_Call{Call: _e.mock.On("HeadReport")} -} - -func (_c *GeneralConfig_HeadReport_Call) Run(run func()) *GeneralConfig_HeadReport_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *GeneralConfig_HeadReport_Call) Return(_a0 config.HeadReport) *GeneralConfig_HeadReport_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *GeneralConfig_HeadReport_Call) RunAndReturn(run func() config.HeadReport) *GeneralConfig_HeadReport_Call { - _c.Call.Return(run) - return _c -} - // Insecure provides a mock function with given fields: func (_m *GeneralConfig) Insecure() config.Insecure { ret := _m.Called() diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index bc60187fb83..f1325d824ea 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -237,9 +237,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 5b1b16eaac2..d752398f039 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -247,9 +247,6 @@ CertFile = '/path/to/cert.pem' TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 1f879a6a1c8..12427650f42 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -237,9 +237,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index bc60187fb83..f1325d824ea 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -237,9 +237,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 04a66e28b7c..9421e6198ee 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -247,9 +247,6 @@ CertFile = '' TransmitQueueMaxSize = 123 TransmitTimeout = '3m54s' -[HeadReport] -TelemetryEnabled = false - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 9894aa95ae9..1c4093cbfca 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -237,9 +237,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 83bc9d59df1..74afcec7400 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1768,19 +1768,6 @@ TransmitTimeout controls how long the transmitter will wait for a response when sending a message to the mercury server, before aborting and considering the transmission to be failed. -## HeadReport -```toml -[HeadReport] -TelemetryEnabled = true # Default -``` - - -### TelemetryEnabled -```toml -TelemetryEnabled = true # Default -``` -TelemetryEnabled controls if it collects information about new blocks from blockchain - ## EVM EVM defaults depend on ChainID: diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index f230a407c50..ff8b4889c49 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -249,9 +249,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 01eccbf327f..f4dd43cb900 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -293,9 +293,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index 6a1e701b762..75a6ae36418 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -293,9 +293,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 582f246c15f..97bae5a84b6 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -293,9 +293,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 8901d4848ca..0cdf001eccd 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -278,9 +278,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index bc6e8dd848c..ab6860ec790 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -283,9 +283,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index c3d734e2661..603fdaada66 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -290,9 +290,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index bc2900e1a91..dea40ec8da0 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -272,9 +272,6 @@ CertFile = '' TransmitQueueMaxSize = 10000 TransmitTimeout = '5s' -[HeadReport] -TelemetryEnabled = true - [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 From b607429fc9eaf5ec28ffeecce4d6e30353ef1231 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Thu, 8 Aug 2024 14:32:41 +0100 Subject: [PATCH 16/21] rebase --- .mockery.yaml | 2 -- core/services/chainlink/config_test.go | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.mockery.yaml b/.mockery.yaml index fc134ef95b0..44c0111fb0d 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -274,8 +274,6 @@ packages: github.com/smartcontractkit/libocr/commontypes: config: dir: "common/types/mocks" -# filename: "{{ .InterfaceName | snakecase }}.go" -# inpackage: true mockname: "Mock{{ .InterfaceName | camelcase }}" interfaces: MonitoringEndpoint: diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 190175f1499..f5a9d335928 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -733,6 +733,7 @@ func TestConfig_Marshal(t *testing.T) { }, VerboseLogging: ptr(true), } + for _, tt := range []struct { name string config Config From 1524bd6d76b9cb5e601338ab49091bc7dcd59ff5 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Thu, 8 Aug 2024 17:04:12 +0100 Subject: [PATCH 17/21] review --- .mockery.yaml | 1 - core/services/chainlink/application.go | 6 ++++- .../headreporter/telemetry_reporter.go | 8 +++---- .../headreporter/telemetry_reporter_test.go | 23 +++---------------- 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/.mockery.yaml b/.mockery.yaml index 44c0111fb0d..37cbff58b1a 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -274,7 +274,6 @@ packages: github.com/smartcontractkit/libocr/commontypes: config: dir: "common/types/mocks" - mockname: "Mock{{ .InterfaceName | camelcase }}" interfaces: MonitoringEndpoint: github.com/smartcontractkit/chainlink/v2/core/services/relay/evm: diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 04eaa8c6905..d89c5fa182e 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -367,7 +367,11 @@ func NewApplication(opts ApplicationOpts) (Application, error) { ) promReporter := headreporter.NewPrometheusReporter(opts.DS, legacyEVMChains) - telemReporter := headreporter.NewTelemetryReporter(legacyEVMChains, telemetryManager) + chainIDs := make([]*big.Int, legacyEVMChains.Len()) + for i, chain := range legacyEVMChains.Slice() { + chainIDs[i] = chain.ID() + } + telemReporter := headreporter.NewTelemetryReporter(telemetryManager, chainIDs...) headReporter := headreporter.NewHeadReporterService(opts.DS, globalLogger, promReporter, telemReporter) srvcs = append(srvcs, headReporter) for _, chain := range legacyEVMChains.Slice() { diff --git a/core/services/headreporter/telemetry_reporter.go b/core/services/headreporter/telemetry_reporter.go index eb7f1ae143d..d76ce8a6044 100644 --- a/core/services/headreporter/telemetry_reporter.go +++ b/core/services/headreporter/telemetry_reporter.go @@ -2,6 +2,7 @@ package headreporter import ( "context" + "math/big" "github.com/pkg/errors" @@ -9,7 +10,6 @@ import ( "google.golang.org/protobuf/proto" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" @@ -19,10 +19,10 @@ type telemetryReporter struct { endpoints map[uint64]commontypes.MonitoringEndpoint } -func NewTelemetryReporter(chainContainer legacyevm.LegacyChainContainer, monitoringEndpointGen telemetry.MonitoringEndpointGenerator) HeadReporter { +func NewTelemetryReporter(monitoringEndpointGen telemetry.MonitoringEndpointGenerator, chainIDs ...*big.Int) HeadReporter { endpoints := make(map[uint64]commontypes.MonitoringEndpoint) - for _, chain := range chainContainer.Slice() { - endpoints[chain.ID().Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chain.ID().String(), "", synchronization.HeadReport) + for _, chainID := range chainIDs { + endpoints[chainID.Uint64()] = monitoringEndpointGen.GenMonitoringEndpoint("EVM", chainID.String(), "", synchronization.HeadReport) } return &telemetryReporter{endpoints: endpoints} } diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go index 7f284f3fcc8..61b3dc64f7c 100644 --- a/core/services/headreporter/telemetry_reporter_test.go +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -12,8 +12,6 @@ import ( mocks2 "github.com/smartcontractkit/chainlink/v2/common/types/mocks" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" @@ -22,11 +20,6 @@ import ( ) func Test_TelemetryReporter_NewHead(t *testing.T) { - chain := mocks.NewChain(t) - chain.On("ID").Return(big.NewInt(100)) - - chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) - head := evmtypes.Head{ Number: 42, EVMChainID: ubig.NewI(100), @@ -61,18 +54,13 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(monitoringEndpoint) - reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) err = reporter.ReportNewHead(testutils.Context(t), &head) assert.NoError(t, err) } func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { - chain := mocks.NewChain(t) - chain.On("ID").Return(big.NewInt(100)) - - chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) - head := evmtypes.Head{ Number: 42, EVMChainID: ubig.NewI(100), @@ -96,24 +84,19 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(monitoringEndpoint) - reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) err = reporter.ReportNewHead(testutils.Context(t), &head) assert.Errorf(t, err, "No finalized block was found for chain_id=100") } func Test_TelemetryReporter_NewHead_MissingEndpoint(t *testing.T) { - chain := mocks.NewChain(t) - chain.On("ID").Return(big.NewInt(100)) - - chains := legacyevm.NewLegacyChains(map[string]legacyevm.Chain{"100": chain}, nil) - monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) monitoringEndpointGen. On("GenMonitoringEndpoint", "EVM", "100", "", synchronization.HeadReport). Return(nil) - reporter := headreporter.NewTelemetryReporter(chains, monitoringEndpointGen) + reporter := headreporter.NewTelemetryReporter(monitoringEndpointGen, big.NewInt(100)) head := evmtypes.Head{Number: 42, EVMChainID: ubig.NewI(100)} From cc3ee3e2746c3ccdec1676010d336c26d85c060d Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Thu, 8 Aug 2024 18:57:47 +0100 Subject: [PATCH 18/21] regenerate --- common/types/mocks/monitoring_endpoint.go | 34 +++++++++---------- .../headreporter/telemetry_reporter_test.go | 4 +-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/common/types/mocks/monitoring_endpoint.go b/common/types/mocks/monitoring_endpoint.go index c5a2fbdaae5..5afc04c9090 100644 --- a/common/types/mocks/monitoring_endpoint.go +++ b/common/types/mocks/monitoring_endpoint.go @@ -4,59 +4,59 @@ package mocks import mock "github.com/stretchr/testify/mock" -// MockMonitoringEndpoint is an autogenerated mock type for the MonitoringEndpoint type -type MockMonitoringEndpoint struct { +// MonitoringEndpoint is an autogenerated mock type for the MonitoringEndpoint type +type MonitoringEndpoint struct { mock.Mock } -type MockMonitoringEndpoint_Expecter struct { +type MonitoringEndpoint_Expecter struct { mock *mock.Mock } -func (_m *MockMonitoringEndpoint) EXPECT() *MockMonitoringEndpoint_Expecter { - return &MockMonitoringEndpoint_Expecter{mock: &_m.Mock} +func (_m *MonitoringEndpoint) EXPECT() *MonitoringEndpoint_Expecter { + return &MonitoringEndpoint_Expecter{mock: &_m.Mock} } // SendLog provides a mock function with given fields: log -func (_m *MockMonitoringEndpoint) SendLog(log []byte) { +func (_m *MonitoringEndpoint) SendLog(log []byte) { _m.Called(log) } -// MockMonitoringEndpoint_SendLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendLog' -type MockMonitoringEndpoint_SendLog_Call struct { +// MonitoringEndpoint_SendLog_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendLog' +type MonitoringEndpoint_SendLog_Call struct { *mock.Call } // SendLog is a helper method to define mock.On call // - log []byte -func (_e *MockMonitoringEndpoint_Expecter) SendLog(log interface{}) *MockMonitoringEndpoint_SendLog_Call { - return &MockMonitoringEndpoint_SendLog_Call{Call: _e.mock.On("SendLog", log)} +func (_e *MonitoringEndpoint_Expecter) SendLog(log interface{}) *MonitoringEndpoint_SendLog_Call { + return &MonitoringEndpoint_SendLog_Call{Call: _e.mock.On("SendLog", log)} } -func (_c *MockMonitoringEndpoint_SendLog_Call) Run(run func(log []byte)) *MockMonitoringEndpoint_SendLog_Call { +func (_c *MonitoringEndpoint_SendLog_Call) Run(run func(log []byte)) *MonitoringEndpoint_SendLog_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].([]byte)) }) return _c } -func (_c *MockMonitoringEndpoint_SendLog_Call) Return() *MockMonitoringEndpoint_SendLog_Call { +func (_c *MonitoringEndpoint_SendLog_Call) Return() *MonitoringEndpoint_SendLog_Call { _c.Call.Return() return _c } -func (_c *MockMonitoringEndpoint_SendLog_Call) RunAndReturn(run func([]byte)) *MockMonitoringEndpoint_SendLog_Call { +func (_c *MonitoringEndpoint_SendLog_Call) RunAndReturn(run func([]byte)) *MonitoringEndpoint_SendLog_Call { _c.Call.Return(run) return _c } -// NewMockMonitoringEndpoint creates a new instance of MockMonitoringEndpoint. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// NewMonitoringEndpoint creates a new instance of MonitoringEndpoint. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. -func NewMockMonitoringEndpoint(t interface { +func NewMonitoringEndpoint(t interface { mock.TestingT Cleanup(func()) -}) *MockMonitoringEndpoint { - mock := &MockMonitoringEndpoint{} +}) *MonitoringEndpoint { + mock := &MonitoringEndpoint{} mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/core/services/headreporter/telemetry_reporter_test.go b/core/services/headreporter/telemetry_reporter_test.go index 61b3dc64f7c..c33edab0bcf 100644 --- a/core/services/headreporter/telemetry_reporter_test.go +++ b/core/services/headreporter/telemetry_reporter_test.go @@ -47,7 +47,7 @@ func Test_TelemetryReporter_NewHead(t *testing.T) { }) assert.NoError(t, err) - monitoringEndpoint := mocks2.NewMockMonitoringEndpoint(t) + monitoringEndpoint := mocks2.NewMonitoringEndpoint(t) monitoringEndpoint.On("SendLog", requestBytes).Return() monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) @@ -77,7 +77,7 @@ func Test_TelemetryReporter_NewHeadMissingFinalized(t *testing.T) { }) assert.NoError(t, err) - monitoringEndpoint := mocks2.NewMockMonitoringEndpoint(t) + monitoringEndpoint := mocks2.NewMonitoringEndpoint(t) monitoringEndpoint.On("SendLog", requestBytes).Return() monitoringEndpointGen := telemetry.NewMockMonitoringEndpointGenerator(t) From 9aad618763a0a145e86446efec85a2cf6cea1f8e Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Mon, 12 Aug 2024 11:49:03 +0100 Subject: [PATCH 19/21] cl node timeout --- integration-tests/testconfig/vrfv2plus/vrfv2plus.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 88ca12975f6..860c0c158bf 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -19,6 +19,7 @@ MaxSize = '0b' [WebServer] AllowOrigins = '*' HTTPPort = 6688 +HTTPWriteTimeout = '1m0s' SecureCookies = false [WebServer.RateLimit] From 1a45a91f09052e2dee9102eda4a6e7b079c03324 Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Mon, 12 Aug 2024 17:07:08 +0100 Subject: [PATCH 20/21] review fix --- core/services/synchronization/telem/telem_head_report.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/services/synchronization/telem/telem_head_report.proto b/core/services/synchronization/telem/telem_head_report.proto index e5a5edcd4b1..6f4cf2ddae6 100644 --- a/core/services/synchronization/telem/telem_head_report.proto +++ b/core/services/synchronization/telem/telem_head_report.proto @@ -5,7 +5,7 @@ option go_package = "github.com/smartcontractkit/chainlink/v2/core/services/sync package telem; message HeadReportRequest { - string chain = 1; + string chainID = 1; Block latest = 2; optional Block finalized = 3; } From b94bcf433d09546accb54f81ed5e1eed80d1f16f Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata Date: Tue, 13 Aug 2024 10:07:34 +0100 Subject: [PATCH 21/21] rebase --- core/services/chainlink/application.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index d89c5fa182e..98067821f99 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -23,10 +23,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - "github.com/smartcontractkit/chainlink/v2/core/capabilities" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/services/standardcapabilities" - "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/build"