From 493bb0eb819b38a488c7776ff5f174152b4f7173 Mon Sep 17 00:00:00 2001 From: Patrick Schork <354473+pschork@users.noreply.github.com> Date: Wed, 30 Oct 2024 18:03:42 -0700 Subject: [PATCH] Add per quorum stake % and semver install base % to semver report ``` +-------------+---------------------+-----------+----------------------+-----------------------+----------------------+ | SEMVER | INSTALL % | OPERATORS | QUORUM 0 STAKE % | QUORUM 1 STAKE % | QUORUM 2 STAKE % | +-------------+---------------------+-----------+----------------------+-----------------------+----------------------+ | 0.8.3 | 20.642201834862387 | 45 | 33.15679224277452 | 8.83955306598433 | 13.210911506047795 | | <0.8.0 | 8.256880733944955 | 18 | 0.054015097747199314 | 0.025964291217224864 | 0 | | refused | 0.9174311926605505 | 2 | 4.382860490796604 | 0.0013047926052436618 | 0 | | timeout | 6.422018348623854 | 14 | 7.235050394332989 | 0.2290448818845607 | 2.2662084387932895 | | filtered | 0.45871559633027525 | 1 | 0 | 3.142158057858368e-05 | 0 | | src-compile | 46.788990825688074 | 102 | 45.597099094040054 | 15.755535049527266 | 84.51559437667252 | | 0.8.2 | 0.45871559633027525 | 1 | 0.009784179765765861 | 0.0010593853034541422 | 0 | | 0.0.0 | 8.715596330275229 | 19 | 3.4357264670142875 | 74.39174915868357 | 0 | | 0.8.0 | 7.339449541284404 | 16 | 6.128672033528587 | 0.7557579532137813 | 0.007285678486380705 | +-------------+---------------------+-----------+----------------------+-----------------------+----------------------+ | TOTALS | 100.00000000000001 | 218 | 100 | 100.00000000000001 | 99.99999999999999 | +-------------+---------------------+-----------+----------------------+-----------------------+----------------------+ ``` --- disperser/common/semver/semver.go | 40 ++++++++++++++++++++++++--- go.mod | 2 +- go.sum | 3 ++- tools/semverscan/cmd/main.go | 45 ++++++++++++++++++++++--------- 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/disperser/common/semver/semver.go b/disperser/common/semver/semver.go index bf4314f073..5db5a1117e 100644 --- a/disperser/common/semver/semver.go +++ b/disperser/common/semver/semver.go @@ -2,6 +2,7 @@ package semver import ( "context" + "math/big" "strings" "sync" "time" @@ -13,10 +14,17 @@ import ( "google.golang.org/grpc/credentials/insecure" ) -func ScanOperators(operators map[core.OperatorID]*core.IndexedOperatorInfo, useRetrievalSocket bool, numWorkers int, nodeInfoTimeout time.Duration, logger logging.Logger) map[string]int { +type SemverMetrics struct { + Semver string `json:"semver"` + Operators uint8 `json:"count"` + OperatorIds []string `json:"operators"` + QuorumStakePercentage map[uint8]float64 `json:"stake_percentage"` +} + +func ScanOperators(operators map[core.OperatorID]*core.IndexedOperatorInfo, operatorState *core.OperatorState, useRetrievalSocket bool, numWorkers int, nodeInfoTimeout time.Duration, logger logging.Logger) map[string]*SemverMetrics { var wg sync.WaitGroup var mu sync.Mutex - semvers := make(map[string]int) + semvers := make(map[string]*SemverMetrics) operatorChan := make(chan core.OperatorID, len(operators)) worker := func() { for operatorId := range operatorChan { @@ -30,7 +38,33 @@ func ScanOperators(operators map[core.OperatorID]*core.IndexedOperatorInfo, useR semver := GetSemverInfo(context.Background(), socket, useRetrievalSocket, operatorId, logger, nodeInfoTimeout) mu.Lock() - semvers[semver]++ + if _, exists := semvers[semver]; !exists { + semvers[semver] = &SemverMetrics{ + Semver: semver, + Operators: 1, + OperatorIds: []string{operatorId.Hex()}, + QuorumStakePercentage: make(map[uint8]float64), + } + } else { + semvers[semver].Operators += 1 + semvers[semver].OperatorIds = append(semvers[semver].OperatorIds, operatorId.Hex()) + } + + // Calculate stake percentage for each quorum + for quorum, totalOperatorInfo := range operatorState.Totals { + stakePercentage := float64(0) + if stake, ok := operatorState.Operators[quorum][operatorId]; ok { + totalStake := new(big.Float).SetInt(totalOperatorInfo.Stake) + operatorStake := new(big.Float).SetInt(stake.Stake) + stakePercentage, _ = new(big.Float).Mul(big.NewFloat(100), new(big.Float).Quo(operatorStake, totalStake)).Float64() + } + + if _, exists := semvers[semver].QuorumStakePercentage[quorum]; !exists { + semvers[semver].QuorumStakePercentage[quorum] = stakePercentage + } else { + semvers[semver].QuorumStakePercentage[quorum] += stakePercentage + } + } mu.Unlock() } wg.Done() diff --git a/go.mod b/go.mod index 9807964a06..6bbf29a217 100644 --- a/go.mod +++ b/go.mod @@ -119,7 +119,7 @@ require ( github.com/lmittmann/tint v1.0.4 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect diff --git a/go.sum b/go.sum index e4c17240b4..5ee6d5ec45 100644 --- a/go.sum +++ b/go.sum @@ -360,8 +360,9 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= diff --git a/tools/semverscan/cmd/main.go b/tools/semverscan/cmd/main.go index f9e9eb6bcb..99372384e6 100644 --- a/tools/semverscan/cmd/main.go +++ b/tools/semverscan/cmd/main.go @@ -59,15 +59,16 @@ func RunScan(ctx *cli.Context) error { if err != nil { log.Fatalln("could not start tcp listener", err) } - cs := eth.NewChainState(tx, gethClient) + chainState := eth.NewChainState(tx, gethClient) logger.Info("Connecting to subgraph", "url", config.ChainStateConfig.Endpoint) - ics := thegraph.MakeIndexedChainState(config.ChainStateConfig, cs, logger) + ics := thegraph.MakeIndexedChainState(config.ChainStateConfig, chainState, logger) currentBlock, err := ics.GetCurrentBlockNumber() if err != nil { return fmt.Errorf("failed to fetch current block number - %s", err) } + operatorState, err := chainState.GetOperatorState(context.Background(), currentBlock, []core.QuorumID{0, 1, 2}) operators, err := ics.GetIndexedOperators(context.Background(), currentBlock) if err != nil { return fmt.Errorf("failed to fetch indexed operator state - %s", err) @@ -85,23 +86,43 @@ func RunScan(ctx *cli.Context) error { } logger.Info("Queried operator state", "count", len(operators)) - semvers := semver.ScanOperators(operators, config.UseRetrievalClient, config.Workers, config.Timeout, logger) + semvers := semver.ScanOperators(operators, operatorState, config.UseRetrievalClient, config.Workers, config.Timeout, logger) + for semver, metrics := range semvers { + logger.Info("Semver Report", "semver", semver, "operators", metrics.Operators, "stake", metrics.QuorumStakePercentage) + } displayResults(semvers) return nil } -func displayResults(results map[string]int) { +func displayResults(results map[string]*semver.SemverMetrics) { tw := table.NewWriter() + rowAutoMerge := table.RowConfig{AutoMerge: true} + tw.AppendHeader(table.Row{"semver", "install %", "operators", "quorum 0 stake %", "quorum 1 stake %", "quorum 2 stake %"}, rowAutoMerge) + //tw.AppendHeader(table.Row{"", "", "quorum 0", "quorum 1", "quorum 2"}) - rowHeader := table.Row{"semver", "count"} - tw.AppendHeader(rowHeader) - - total := 0 - for semver, count := range results { - tw.AppendRow(table.Row{semver, count}) - total += count + total_operators := 0 + total_semver_pct := 0.0 + total_stake_q0 := 0.0 + total_stake_q1 := 0.0 + total_stake_q2 := 0.0 + for _, metrics := range results { + total_operators += int(metrics.Operators) + total_stake_q0 += metrics.QuorumStakePercentage[0] + total_stake_q1 += metrics.QuorumStakePercentage[1] + total_stake_q2 += metrics.QuorumStakePercentage[2] + } + for semver, metrics := range results { + semver_pct := 100 * (float64(metrics.Operators) / float64(total_operators)) + total_semver_pct += semver_pct + tw.AppendRow(table.Row{semver, semver_pct, metrics.Operators, metrics.QuorumStakePercentage[0], metrics.QuorumStakePercentage[1], metrics.QuorumStakePercentage[2]}) } - tw.AppendFooter(table.Row{"total", total}) + tw.AppendFooter(table.Row{"totals", total_semver_pct, total_operators, total_stake_q0, total_stake_q1, total_stake_q2}) + tw.SetColumnConfigs([]table.ColumnConfig{ + {Number: 1, AutoMerge: true}, + {Number: 3, AlignHeader: 2}, + {Number: 4, AlignHeader: 2}, + {Number: 5, AlignHeader: 2}, + }) fmt.Println(tw.Render()) }