diff --git a/app/app.go b/app/app.go index ff3a1a222..114443708 100644 --- a/app/app.go +++ b/app/app.go @@ -234,7 +234,7 @@ func Run(ctx context.Context, conf Config) (err error) { sender := new(p2p.Sender) - wirePeerInfo(life, tcpNode, peerIDs, cluster.InitialMutationHash, sender) + wirePeerInfo(life, tcpNode, peerIDs, cluster.InitialMutationHash, sender, conf.BuilderAPI) qbftDebug := newQBFTDebugger() @@ -274,9 +274,9 @@ func Run(ctx context.Context, conf Config) (err error) { } // wirePeerInfo wires the peerinfo protocol. -func wirePeerInfo(life *lifecycle.Manager, tcpNode host.Host, peers []peer.ID, lockHash []byte, sender *p2p.Sender) { +func wirePeerInfo(life *lifecycle.Manager, tcpNode host.Host, peers []peer.ID, lockHash []byte, sender *p2p.Sender, builderEnabled bool) { gitHash, _ := version.GitCommit() - peerInfo := peerinfo.New(tcpNode, peers, version.Version, lockHash, gitHash, sender.SendReceive) + peerInfo := peerinfo.New(tcpNode, peers, version.Version, lockHash, gitHash, sender.SendReceive, builderEnabled) life.RegisterStart(lifecycle.AsyncAppCtx, lifecycle.StartPeerInfo, lifecycle.HookFuncCtx(peerInfo.Run)) } diff --git a/app/peerinfo/adhoc_test.go b/app/peerinfo/adhoc_test.go index a81357fef..ce1d08ce0 100644 --- a/app/peerinfo/adhoc_test.go +++ b/app/peerinfo/adhoc_test.go @@ -26,7 +26,7 @@ func TestDoOnce(t *testing.T) { lockHash := []byte("123") gitHash := "abc" // Register the server handler that either - _ = peerinfo.New(server, []peer.ID{server.ID(), client.ID()}, vers, lockHash, gitHash, p2p.SendReceive) + _ = peerinfo.New(server, []peer.ID{server.ID(), client.ID()}, vers, lockHash, gitHash, p2p.SendReceive, true) info, _, ok, err := peerinfo.DoOnce(context.Background(), client, server.ID()) require.NoError(t, err) @@ -34,4 +34,5 @@ func TestDoOnce(t *testing.T) { require.Equal(t, vers.String(), info.CharonVersion) require.Equal(t, gitHash, info.GitHash) require.Equal(t, lockHash, info.LockHash) + require.True(t, info.BuilderApiEnabled) } diff --git a/app/peerinfo/metrics.go b/app/peerinfo/metrics.go index e5d98320e..14f3ecadc 100644 --- a/app/peerinfo/metrics.go +++ b/app/peerinfo/metrics.go @@ -53,4 +53,11 @@ var ( Name: "version_support", Help: "Set to 1 if the peer's version is supported by (compatible with) the current version, else 0 if unsupported.", }, []string{"peer"}) + + peerBuilderAPIEnabledGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: "app", + Subsystem: "peerinfo", + Name: "builder_api_enabled", + Help: "Set to 1 if builder API is enabled on this peer, else 0 if disabled.", + }, []string{"peer"}) ) diff --git a/app/peerinfo/peerinfo.go b/app/peerinfo/peerinfo.go index c85cea85f..41ce0edec 100644 --- a/app/peerinfo/peerinfo.go +++ b/app/peerinfo/peerinfo.go @@ -39,12 +39,12 @@ func Protocols() []protocol.ID { type ( tickerProvider func() (<-chan time.Time, func()) nowFunc func() time.Time - metricSubmitter func(peerID peer.ID, clockOffset time.Duration, version, gitHash string, startTime time.Time) + metricSubmitter func(peerID peer.ID, clockOffset time.Duration, version, gitHash string, startTime time.Time, builderAPIEnabled bool) ) // New returns a new peer info protocol instance. func New(tcpNode host.Host, peers []peer.ID, version version.SemVer, lockHash []byte, gitHash string, - sendFunc p2p.SendReceiveFunc, + sendFunc p2p.SendReceiveFunc, builderEnabled bool, ) *PeerInfo { // Set own version and git hash and start time metrics. name := p2p.PeerName(tcpNode.ID()) @@ -52,6 +52,12 @@ func New(tcpNode host.Host, peers []peer.ID, version version.SemVer, lockHash [] peerGitHash.WithLabelValues(name, gitHash).Set(1) peerStartGauge.WithLabelValues(name).Set(float64(time.Now().Unix())) + if builderEnabled { + peerBuilderAPIEnabledGauge.WithLabelValues(name).Set(1) + } else { + peerBuilderAPIEnabledGauge.WithLabelValues(name).Set(0) + } + for i, p := range peers { peerIndexGauge.WithLabelValues(p2p.PeerName(p)).Set(float64(i)) } @@ -62,22 +68,24 @@ func New(tcpNode host.Host, peers []peer.ID, version version.SemVer, lockHash [] } return newInternal(tcpNode, peers, version, lockHash, gitHash, sendFunc, p2p.RegisterHandler, - tickerProvider, time.Now, newMetricsSubmitter()) + tickerProvider, time.Now, newMetricsSubmitter(), builderEnabled) } // NewForT returns a new peer info protocol instance for testing only. func NewForT(_ *testing.T, tcpNode host.Host, peers []peer.ID, version version.SemVer, lockHash []byte, gitHash string, sendFunc p2p.SendReceiveFunc, registerHandler p2p.RegisterHandlerFunc, tickerProvider tickerProvider, nowFunc nowFunc, metricSubmitter metricSubmitter, + builderAPIEnabled bool, ) *PeerInfo { return newInternal(tcpNode, peers, version, lockHash, gitHash, sendFunc, registerHandler, - tickerProvider, nowFunc, metricSubmitter) + tickerProvider, nowFunc, metricSubmitter, builderAPIEnabled) } // newInternal returns a new instance for New or NewForT. func newInternal(tcpNode host.Host, peers []peer.ID, version version.SemVer, lockHash []byte, gitHash string, sendFunc p2p.SendReceiveFunc, registerHandler p2p.RegisterHandlerFunc, tickerProvider tickerProvider, nowFunc nowFunc, metricSubmitter metricSubmitter, + builderAPIEnabled bool, ) *PeerInfo { startTime := timestamppb.New(nowFunc()) @@ -86,11 +94,12 @@ func newInternal(tcpNode host.Host, peers []peer.ID, version version.SemVer, loc func() proto.Message { return new(pbv1.PeerInfo) }, func(context.Context, peer.ID, proto.Message) (proto.Message, bool, error) { return &pbv1.PeerInfo{ - CharonVersion: version.String(), - LockHash: lockHash, - GitHash: gitHash, - SentAt: timestamppb.New(nowFunc()), - StartedAt: startTime, + CharonVersion: version.String(), + LockHash: lockHash, + GitHash: gitHash, + SentAt: timestamppb.New(nowFunc()), + StartedAt: startTime, + BuilderApiEnabled: builderAPIEnabled, }, true, nil }, ) @@ -104,33 +113,35 @@ func newInternal(tcpNode host.Host, peers []peer.ID, version version.SemVer, loc } return &PeerInfo{ - sendFunc: sendFunc, - tcpNode: tcpNode, - peers: peers, - version: version, - lockHash: lockHash, - startTime: startTime, - metricSubmitter: metricSubmitter, - tickerProvider: tickerProvider, - nowFunc: nowFunc, - lockHashFilters: lockHashFilters, - versionFilters: versionFilters, + sendFunc: sendFunc, + tcpNode: tcpNode, + peers: peers, + version: version, + lockHash: lockHash, + startTime: startTime, + builderAPIEnabled: builderAPIEnabled, + metricSubmitter: metricSubmitter, + tickerProvider: tickerProvider, + nowFunc: nowFunc, + lockHashFilters: lockHashFilters, + versionFilters: versionFilters, } } type PeerInfo struct { - sendFunc p2p.SendReceiveFunc - tcpNode host.Host - peers []peer.ID - version version.SemVer - lockHash []byte - gitHash string - startTime *timestamppb.Timestamp - tickerProvider tickerProvider - metricSubmitter metricSubmitter - nowFunc func() time.Time - lockHashFilters map[peer.ID]z.Field - versionFilters map[peer.ID]z.Field + sendFunc p2p.SendReceiveFunc + tcpNode host.Host + peers []peer.ID + version version.SemVer + lockHash []byte + gitHash string + startTime *timestamppb.Timestamp + builderAPIEnabled bool + tickerProvider tickerProvider + metricSubmitter metricSubmitter + nowFunc func() time.Time + lockHashFilters map[peer.ID]z.Field + versionFilters map[peer.ID]z.Field } // Run runs the peer info protocol until the context is cancelled. @@ -158,11 +169,12 @@ func (p *PeerInfo) sendOnce(ctx context.Context, now time.Time) { } req := &pbv1.PeerInfo{ - CharonVersion: p.version.String(), - LockHash: p.lockHash, - GitHash: p.gitHash, - SentAt: timestamppb.New(now), - StartedAt: p.startTime, + CharonVersion: p.version.String(), + LockHash: p.lockHash, + GitHash: p.gitHash, + SentAt: timestamppb.New(now), + StartedAt: p.startTime, + BuilderApiEnabled: p.builderAPIEnabled, } go func(peerID peer.ID) { @@ -209,7 +221,7 @@ func (p *PeerInfo) sendOnce(ctx context.Context, now time.Time) { // Set peer compatibility to true. peerCompatibleGauge.WithLabelValues(name).Set(1) - p.metricSubmitter(peerID, clockOffset, resp.CharonVersion, resp.GitHash, resp.StartedAt.AsTime()) + p.metricSubmitter(peerID, clockOffset, resp.CharonVersion, resp.GitHash, resp.StartedAt.AsTime(), resp.BuilderApiEnabled) // Log unexpected lock hash if !bytes.Equal(resp.LockHash, p.lockHash) { @@ -221,6 +233,15 @@ func (p *PeerInfo) sendOnce(ctx context.Context, now time.Time) { p.lockHashFilters[peerID], ) } + + // Builder API shall be either enabled or disabled for both. + if resp.BuilderApiEnabled != p.builderAPIEnabled { + log.Warn(ctx, "Mismatching peer builder API status", nil, + z.Str("peer", name), + z.Bool("peer_builder_api_enabled", resp.BuilderApiEnabled), + z.Bool("builder_api_enabled", p.builderAPIEnabled), + ) + } }(peerID) } } @@ -250,7 +271,7 @@ func supportedPeerVersion(peerVersion string, supported []version.SemVer) error // newMetricsSubmitter returns a prometheus metric submitter. func newMetricsSubmitter() metricSubmitter { return func(peerID peer.ID, clockOffset time.Duration, version string, gitHash string, - startTime time.Time, + startTime time.Time, builderAPIEnabled bool, ) { peerName := p2p.PeerName(peerID) @@ -279,5 +300,11 @@ func newMetricsSubmitter() metricSubmitter { peerVersion.WithLabelValues(peerName, version).Set(1) peerGitHash.Reset(peerName) peerGitHash.WithLabelValues(peerName, gitHash).Set(1) + + if builderAPIEnabled { + peerBuilderAPIEnabledGauge.WithLabelValues(peerName).Set(1) + } else { + peerBuilderAPIEnabledGauge.WithLabelValues(peerName).Set(0) + } } } diff --git a/app/peerinfo/peerinfo_internal_test.go b/app/peerinfo/peerinfo_internal_test.go index c62d9efa7..0fcb9e14e 100644 --- a/app/peerinfo/peerinfo_internal_test.go +++ b/app/peerinfo/peerinfo_internal_test.go @@ -3,11 +3,17 @@ package peerinfo import ( + "fmt" + "strings" "testing" + "github.com/libp2p/go-libp2p/core/peer" + promtestutil "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "github.com/obolnetwork/charon/app/version" + "github.com/obolnetwork/charon/p2p" + "github.com/obolnetwork/charon/testutil" ) func TestSupporterVersion(t *testing.T) { @@ -59,6 +65,40 @@ func TestSupporterVersion(t *testing.T) { } } +func TestPeerBuilderAPIEnabledGauge(t *testing.T) { + server := testutil.CreateHost(t, testutil.AvailableAddr(t)) + client := testutil.CreateHost(t, testutil.AvailableAddr(t)) + + lockHash := []byte("123") + gitHash := "abc" + peerName := p2p.PeerName(server.ID()) + + tests := []struct { + name string + builderEnabled bool + expectedValue int + }{ + {"builder enabled", true, 1}, + {"builder disabled", false, 0}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _ = New(server, []peer.ID{server.ID(), client.ID()}, version.Version, lockHash, gitHash, nil, test.builderEnabled) + + expectedMetric := fmt.Sprintf(` + # HELP app_peerinfo_builder_api_enabled Set to 1 if builder API is enabled on this peer, else 0 if disabled. + # TYPE app_peerinfo_builder_api_enabled gauge + app_peerinfo_builder_api_enabled{ peer = "%s" } %d + `, peerName, test.expectedValue) + + if err := promtestutil.CollectAndCompare(peerBuilderAPIEnabledGauge, strings.NewReader(expectedMetric), "app_peerinfo_builder_api_enabled"); err != nil { + require.NoError(t, err, "failed to collect metric") + } + }) + } +} + func semvers(s ...string) []version.SemVer { var resp []version.SemVer for _, v := range s { diff --git a/app/peerinfo/peerinfo_test.go b/app/peerinfo/peerinfo_test.go index 4b3186abe..3db32bd60 100644 --- a/app/peerinfo/peerinfo_test.go +++ b/app/peerinfo/peerinfo_test.go @@ -86,7 +86,7 @@ func TestPeerInfo(t *testing.T) { tickProvider := func() (<-chan time.Time, func()) { return nil, func() {} } - metricSubmitter := func(peer.ID, time.Duration, string, string, time.Time) { + metricSubmitter := func(peer.ID, time.Duration, string, string, time.Time, bool) { panic("unexpected metric submitted") } @@ -101,7 +101,7 @@ func TestPeerInfo(t *testing.T) { var submittedMutex sync.Mutex var submitted int - metricSubmitter = func(peerID peer.ID, clockOffset time.Duration, version, gitHash string, startTime time.Time) { + metricSubmitter = func(peerID peer.ID, clockOffset time.Duration, version, gitHash string, startTime time.Time, builderEnabled bool) { for i, tcpNode := range tcpNodes { if tcpNode.ID() != peerID { continue @@ -110,6 +110,7 @@ func TestPeerInfo(t *testing.T) { require.Equal(t, node.Version.String(), version) require.Equal(t, gitCommit, gitHash) require.Equal(t, nowFunc(i)().Unix(), startTime.Unix()) + require.True(t, builderEnabled) submittedMutex.Lock() submitted++ @@ -125,7 +126,7 @@ func TestPeerInfo(t *testing.T) { } peerInfo := peerinfo.NewForT(t, tcpNodes[i], peers, node.Version, node.LockHash, gitCommit, p2p.SendReceive, p2p.RegisterHandler, - tickProvider, nowFunc(i), metricSubmitter) + tickProvider, nowFunc(i), metricSubmitter, true) peerInfos = append(peerInfos, peerInfo) } diff --git a/app/peerinfo/peerinfopb/v1/peerinfo.pb.go b/app/peerinfo/peerinfopb/v1/peerinfo.pb.go index 4c8ff801a..0e5acdfe8 100644 --- a/app/peerinfo/peerinfopb/v1/peerinfo.pb.go +++ b/app/peerinfo/peerinfopb/v1/peerinfo.pb.go @@ -26,11 +26,12 @@ type PeerInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - CharonVersion string `protobuf:"bytes,1,opt,name=charon_version,json=charonVersion,proto3" json:"charon_version,omitempty"` - LockHash []byte `protobuf:"bytes,2,opt,name=lock_hash,json=lockHash,proto3" json:"lock_hash,omitempty"` - SentAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=sent_at,json=sentAt,proto3,oneof" json:"sent_at,omitempty"` - GitHash string `protobuf:"bytes,4,opt,name=git_hash,json=gitHash,proto3" json:"git_hash,omitempty"` - StartedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=started_at,json=startedAt,proto3,oneof" json:"started_at,omitempty"` + CharonVersion string `protobuf:"bytes,1,opt,name=charon_version,json=charonVersion,proto3" json:"charon_version,omitempty"` + LockHash []byte `protobuf:"bytes,2,opt,name=lock_hash,json=lockHash,proto3" json:"lock_hash,omitempty"` + SentAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=sent_at,json=sentAt,proto3,oneof" json:"sent_at,omitempty"` + GitHash string `protobuf:"bytes,4,opt,name=git_hash,json=gitHash,proto3" json:"git_hash,omitempty"` + StartedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=started_at,json=startedAt,proto3,oneof" json:"started_at,omitempty"` + BuilderApiEnabled bool `protobuf:"varint,6,opt,name=builder_api_enabled,json=builderApiEnabled,proto3" json:"builder_api_enabled,omitempty"` } func (x *PeerInfo) Reset() { @@ -100,6 +101,13 @@ func (x *PeerInfo) GetStartedAt() *timestamppb.Timestamp { return nil } +func (x *PeerInfo) GetBuilderApiEnabled() bool { + if x != nil { + return x.BuilderApiEnabled + } + return false +} + var File_app_peerinfo_peerinfopb_v1_peerinfo_proto protoreflect.FileDescriptor var file_app_peerinfo_peerinfopb_v1_peerinfo_proto_rawDesc = []byte{ @@ -109,7 +117,7 @@ var file_app_peerinfo_peerinfopb_v1_peerinfo_proto_rawDesc = []byte{ 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x70, 0x62, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfe, 0x01, 0x0a, 0x08, 0x50, 0x65, 0x65, + 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x02, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x6f, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x68, 0x61, 0x72, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, @@ -123,7 +131,10 @@ var file_app_peerinfo_peerinfopb_v1_peerinfo_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x01, - 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0a, + 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x2e, + 0x0a, 0x13, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x65, 0x72, 0x41, 0x70, 0x69, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x42, 0x3a, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x62, 0x6f, 0x6c, 0x6e, 0x65, 0x74, 0x77, diff --git a/app/peerinfo/peerinfopb/v1/peerinfo.proto b/app/peerinfo/peerinfopb/v1/peerinfo.proto index 8be280928..cdfa70f23 100644 --- a/app/peerinfo/peerinfopb/v1/peerinfo.proto +++ b/app/peerinfo/peerinfopb/v1/peerinfo.proto @@ -12,6 +12,7 @@ message PeerInfo { optional google.protobuf.Timestamp sent_at = 3; string git_hash = 4; optional google.protobuf.Timestamp started_at = 5; + bool builder_api_enabled = 6; // TODO(corver): Always populate timestamps when sending, then make them required after subsequent release. } diff --git a/dkg/dkg.go b/dkg/dkg.go index 0ba4d68aa..ad1978d08 100644 --- a/dkg/dkg.go +++ b/dkg/dkg.go @@ -408,7 +408,7 @@ func setupP2P(ctx context.Context, key *k1.PrivateKey, conf Config, peers []p2p. // Register peerinfo server handler for identification to relays (but do not run peerinfo client). gitHash, _ := version.GitCommit() - _ = peerinfo.New(tcpNode, peerIDs, version.Version, defHash, gitHash, nil) + _ = peerinfo.New(tcpNode, peerIDs, version.Version, defHash, gitHash, nil, false) return tcpNode, func() { _ = tcpNode.Close() diff --git a/docs/metrics.md b/docs/metrics.md index 4f125c882..0b18a37dc 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -23,6 +23,7 @@ when storing metrics from multiple nodes or clusters in one Prometheus instance. | `app_log_warn_total` | Counter | Total count of logged warnings by topic | `topic` | | `app_monitoring_readyz` | Gauge | Set to 1 if the node is operational and monitoring api `/readyz` endpoint is returning 200s. Else `/readyz` is returning 500s and this metric is either set to 2 if the beacon node is down, or3 if the beacon node is syncing, or4 if quorum peers are not connected. | | | `app_peer_name` | Gauge | Constant gauge with label set to the name of the cluster peer | `peer_name` | +| `app_peerinfo_builder_api_enabled` | Gauge | Set to 1 if builder API is enabled on this peer, else 0 if disabled. | `peer` | | `app_peerinfo_clock_offset_seconds` | Gauge | Peer clock offset in seconds | `peer` | | `app_peerinfo_git_commit` | Gauge | Constant gauge with git_hash label set to peer`s git commit hash. | `peer, git_hash` | | `app_peerinfo_index` | Gauge | Constant gauge set to the peer index in the cluster definition | `peer` | diff --git a/testutil/compose/README.md b/testutil/compose/README.md index 0ebda1eb8..bb5be4cae 100644 --- a/testutil/compose/README.md +++ b/testutil/compose/README.md @@ -31,7 +31,7 @@ go install github.com/obolnetwork/charon/testutil/compose/compose # Alternatives: # go install ./... -# cd testutil/compose/compose && go installl . +# cd testutil/compose/compose && go install . # cd testutil/compose/compose && go build -o /tmp/compose/compose ``` diff --git a/testutil/compose/static/grafana/dash_charon_overview.json b/testutil/compose/static/grafana/dash_charon_overview.json index e899226d5..f8882d7d6 100644 --- a/testutil/compose/static/grafana/dash_charon_overview.json +++ b/testutil/compose/static/grafana/dash_charon_overview.json @@ -24,7 +24,7 @@ "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, - "id": 65, + "id": 2, "links": [ { "asDropdown": false, @@ -93,6 +93,7 @@ }, "id": 19, "options": { + "cellHeight": "sm", "footer": { "countRows": false, "fields": "", @@ -104,7 +105,7 @@ "frameIndex": 0, "showHeader": false }, - "pluginVersion": "9.4.3", + "pluginVersion": "10.2.2", "targets": [ { "datasource": { @@ -242,9 +243,10 @@ "titleSize": 15, "valueSize": 15 }, - "textMode": "auto" + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.4.3", + "pluginVersion": "10.2.2", "targets": [ { "datasource": { @@ -474,9 +476,10 @@ "fields": "", "values": false }, - "textMode": "auto" + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.4.3", + "pluginVersion": "10.2.2", "targets": [ { "datasource": { @@ -508,6 +511,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -523,6 +527,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 2, "pointSize": 5, @@ -652,9 +657,10 @@ "titleSize": 15, "valueSize": 15 }, - "textMode": "auto" + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.4.3", + "pluginVersion": "10.2.2", "targets": [ { "datasource": { @@ -987,6 +993,32 @@ "value": 30 } ] + }, + { + "matcher": { + "id": "byName", + "options": "Builder API" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "0": { + "index": 0, + "text": " ❌" + }, + "1": { + "index": 1, + "text": "✅" + } + }, + "type": "value" + } + ] + } + ] } ] }, @@ -998,6 +1030,7 @@ }, "id": 54, "options": { + "cellHeight": "sm", "footer": { "countRows": false, "fields": "", @@ -1015,7 +1048,7 @@ } ] }, - "pluginVersion": "9.4.3", + "pluginVersion": "10.2.2", "targets": [ { "datasource": { @@ -1271,6 +1304,25 @@ "instant": true, "range": false, "refId": "R" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "max(app_peerinfo_builder_api_enabled{cluster_name=\"$cluster_name\",cluster_hash=\"$cluster_hash\",cluster_peer=\"$cluster_peer\"}) by (peer)", + "format": "table", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "S", + "useBackend": false } ], "title": "Peer Connectivity and Duty Participation", @@ -1302,45 +1354,49 @@ "Time 7": true, "Time 8": true, "Time 9": true, + "Value #C": true, + "Value #D": true, + "Value #E": true, "Value #F": false, + "Value #G": true, "Value #L": true, - "Value #M": true + "Value #M": true, + "Value #N": true, + "Value #P": true }, "indexByName": { - "Time 1": 10, - "Time 10": 29, - "Time 11": 30, - "Time 12": 31, - "Time 13": 32, - "Time 14": 33, - "Time 15": 34, - "Time 16": 35, - "Time 17": 36, - "Time 2": 12, - "Time 3": 13, - "Time 4": 14, - "Time 5": 15, - "Time 6": 16, - "Time 7": 17, - "Time 8": 18, - "Time 9": 28, + "Time 1": 11, + "Time 10": 28, + "Time 11": 29, + "Time 12": 30, + "Time 13": 31, + "Time 14": 32, + "Time 15": 33, + "Time 16": 34, + "Time 2": 13, + "Time 3": 14, + "Time 4": 15, + "Time 5": 16, + "Time 6": 17, + "Time 7": 18, + "Time 8": 19, + "Time 9": 27, "Value #A": 3, "Value #B": 5, - "Value #C": 20, - "Value #D": 21, - "Value #E": 22, + "Value #C": 21, + "Value #D": 22, + "Value #E": 23, "Value #F": 2, - "Value #G": 23, - "Value #H": 24, + "Value #G": 24, "Value #J": 6, "Value #K": 4, - "Value #L": 11, - "Value #M": 19, + "Value #L": 12, + "Value #M": 20, "Value #N": 25, - "Value #O": 27, "Value #P": 26, "Value #Q": 9, "Value #R": 1, + "Value #S": 10, "git_hash": 8, "peer": 0, "version": 7 @@ -1363,6 +1419,7 @@ "Value #P": "PrepareContrib", "Value #Q": "Uptime", "Value #R": "Index", + "Value #S": "Builder API", "git_hash": "GitCommit", "peer": "Peer", "version": "Version" @@ -1384,6 +1441,11 @@ }, "custom": { "fillOpacity": 100, + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, "lineWidth": 0 }, "mappings": [], @@ -1470,6 +1532,11 @@ }, "custom": { "fillOpacity": 100, + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, "lineWidth": 0 }, "links": [ @@ -1548,6 +1615,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1561,6 +1629,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -1705,9 +1774,10 @@ "fields": "", "values": false }, - "textMode": "auto" + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.4.3", + "pluginVersion": "10.2.2", "targets": [ { "datasource": { @@ -1736,6 +1806,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1749,6 +1820,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -1947,8 +2019,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2042,8 +2113,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2137,8 +2207,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2232,8 +2301,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2328,8 +2396,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2421,8 +2488,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2542,8 +2608,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2649,8 +2714,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2725,8 +2789,7 @@ "mode": "absolute", "steps": [ { - "color": "light-blue", - "value": null + "color": "light-blue" }, { "color": "red", @@ -2908,7 +2971,6 @@ "refresh": "30s", "revision": 1, "schemaVersion": 38, - "style": "dark", "tags": [ "charon", "cluster-labels" @@ -2917,10 +2979,9 @@ "list": [ { "current": { - "isNone": true, "selected": false, - "text": "None", - "value": "" + "text": "compose-4-1", + "value": "compose-4-1" }, "datasource": { "type": "prometheus", @@ -2947,8 +3008,8 @@ { "current": { "selected": false, - "text": "ad1c2dd", - "value": "ad1c2dd" + "text": "1467820", + "value": "1467820" }, "datasource": { "type": "prometheus", @@ -2975,8 +3036,8 @@ { "current": { "selected": false, - "text": "helpless-state", - "value": "helpless-state" + "text": "anxious-leaves", + "value": "anxious-leaves" }, "datasource": { "type": "prometheus", @@ -3003,8 +3064,8 @@ { "current": { "selected": false, - "text": "node3", - "value": "node3" + "text": "node0", + "value": "node0" }, "datasource": { "type": "prometheus",