Skip to content

Commit

Permalink
[Tokenomics] Update telemetry to include relay mining difficulty and …
Browse files Browse the repository at this point in the history
…EMA (#631)
  • Loading branch information
red-0ne authored Jul 1, 2024
1 parent 9de7577 commit 8593170
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 16 deletions.
202 changes: 201 additions & 1 deletion localnet/grafana-dashboards/stress-test-dashboard.json
Original file line number Diff line number Diff line change
Expand Up @@ -1337,9 +1337,209 @@
],
"title": "Claim Settlement & Expiration",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 32
},
"id": 14,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"maxHeight": 600,
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"disableTextWrap": false,
"editorMode": "builder",
"expr": "avg by(service_id) (event_type_gauge{container=\"poktrolld-validator\", type=\"relay_ema\"})",
"fullMetaSearch": false,
"includeNullMetadata": false,
"instant": false,
"legendFormat": "__auto",
"range": true,
"refId": "A",
"useBackend": false
}
],
"title": "Relays EMA per Service",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 32
},
"id": 15,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"maxHeight": 600,
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"disableTextWrap": false,
"editorMode": "builder",
"expr": "avg by(service_id) (event_type_gauge{container=\"poktrolld-validator\", type=\"relay_mining_difficulty\"})",
"fullMetaSearch": false,
"includeNullMetadata": false,
"instant": false,
"legendFormat": "__auto",
"range": true,
"refId": "A",
"useBackend": false
}
],
"title": "Relay Mining Difficulty per Service",
"type": "timeseries"
}
],
"refresh": "",
"refresh": "5s",
"schemaVersion": 39,
"tags": [
"protocol"
Expand Down
39 changes: 38 additions & 1 deletion telemetry/event_counters.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ import (
prooftypes "github.com/pokt-network/poktroll/x/proof/types"
)

const eventTypeMetricKey = "event_type"
const (
// TODO_DECIDE: Decide if we want to continue using these generic metrics keys
// or opt for specific keys for each event_type.
// See: https://github.com/pokt-network/poktroll/pull/631#discussion_r1653760820
eventTypeMetricKey = "event_type"
eventTypeMetricKeyGauge = "event_type_gauge"
)

// EventSuccessCounter increments a counter with the given data type and success status.
func EventSuccessCounter(
Expand Down Expand Up @@ -120,6 +126,37 @@ func ClaimCounter(
)
}

// RelayMiningDifficultyCounter sets a gauge which tracks the relay mining difficulty,
// which is represented by number of leading zero bits.
// The serviceId is used as a label to be able to track the difficulty for each service.
func RelayMiningDifficultyGauge(numbLeadingZeroBits int, serviceId string) {
labels := []metrics.Label{
{Name: "type", Value: "relay_mining_difficulty"},
{Name: "service_id", Value: serviceId},
}

telemetry.SetGaugeWithLabels(
[]string{eventTypeMetricKeyGauge},
float32(numbLeadingZeroBits),
labels,
)
}

// RelayEMAGauge sets a gauge which tracks the relay EMA for a service.
// The serviceId is used as a label to be able to track the EMA for each service.
func RelayEMAGauge(relayEMA uint64, serviceId string) {
labels := []metrics.Label{
{Name: "type", Value: "relay_ema"},
{Name: "service_id", Value: serviceId},
}

telemetry.SetGaugeWithLabels(
[]string{eventTypeMetricKeyGauge},
float32(relayEMA),
labels,
)
}

// AppendErrLabel appends a label with the name "error" and a value of the error's
// message to the given labels slice if the error is not nil.
func AppendErrLabel(err error, labels ...metrics.Label) []metrics.Label {
Expand Down
4 changes: 2 additions & 2 deletions x/session/keeper/session_hydrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ func (k Keeper) HydrateSession(ctx context.Context, sh *sessionHydrator) (*types
if err := k.hydrateSessionApplication(ctx, sh); err != nil {
return nil, err
}
logger.Info("Finished hydrating session application: %+v", sh.session.Application)
logger.Info(fmt.Sprintf("Finished hydrating session application: %+v", sh.session.Application))

if err := k.hydrateSessionSuppliers(ctx, sh); err != nil {
return nil, err
}
logger.Info("Finished hydrating session suppliers: %+v")
logger.Info("Finished hydrating session suppliers")

sh.session.Header = sh.sessionHeader
sh.session.SessionId = sh.sessionHeader.SessionId
Expand Down
36 changes: 29 additions & 7 deletions x/tokenomics/keeper/update_relay_mining_difficulty.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/hex"
"fmt"
"math"
"math/bits"

sdk "github.com/cosmos/cosmos-sdk/types"

Expand All @@ -14,10 +15,6 @@ import (
"github.com/pokt-network/poktroll/x/tokenomics/types"
)

// TODO_UPNET(@Olshansk, #542): Add telemetry that will enable:
// 1. Visualizing a multi-line chart of "Relays EMA per Service" (title) of "Relay EMA" (y-axis) vs block/time (x-axis) and being able to select each service.
// 1. Visualizing a multi-line chart of "Relay Mining Difficulty per service" (title) of "Relay EMA" (y-axis) vs block/time (x-axis) and being able to select each service.

const (
// Exponential moving average (ema) smoothing factor, commonly known as alpha.
// Usually, alpha = 2 / (N+1), where N is the number of periods.
Expand All @@ -40,10 +37,11 @@ const (
func (k Keeper) UpdateRelayMiningDifficulty(
ctx context.Context,
relaysPerServiceMap map[string]uint64,
) error {
) (difficultyPerServiceMap map[string]types.RelayMiningDifficulty, err error) {
logger := k.Logger().With("method", "UpdateRelayMiningDifficulty")
sdkCtx := sdk.UnwrapSDKContext(ctx)

difficultyPerServiceMap = make(map[string]types.RelayMiningDifficulty, len(relaysPerServiceMap))
for serviceId, numRelays := range relaysPerServiceMap {
prevDifficulty, found := k.GetRelayMiningDifficulty(ctx, serviceId)
if !found {
Expand Down Expand Up @@ -88,7 +86,7 @@ func (k Keeper) UpdateRelayMiningDifficulty(
NewNumRelaysEma: newDifficulty.NumRelaysEma,
}
if err := sdkCtx.EventManager().EmitTypedEvent(&relayMiningDifficultyUpdateEvent); err != nil {
return err
return nil, err
}

// Output the appropriate log message based on whether the difficulty was initialized, updated or unchanged.
Expand All @@ -102,9 +100,14 @@ func (k Keeper) UpdateRelayMiningDifficulty(
logMessage = fmt.Sprintf("No change in RelayMiningDifficulty for service %s at height %d. Current difficulty: %x", serviceId, sdkCtx.BlockHeight(), newDifficulty.TargetHash)
}
logger.Info(logMessage)

// Store the updated difficulty in the map for telemetry.
// This is done to only emit the telemetry event if all the difficulties
// are updated successfully.
difficultyPerServiceMap[serviceId] = newDifficulty
}

return nil
return difficultyPerServiceMap, nil
}

// ComputeNewDifficultyTargetHash computes the new difficulty target hash based
Expand Down Expand Up @@ -156,6 +159,25 @@ func computeEma(alpha float64, prevEma, currValue uint64) uint64 {
return uint64(alpha*float64(currValue) + (1-alpha)*float64(prevEma))
}

// RelayMiningTargetHashToDifficulty returns the relay mining difficulty based on the hash.
// This currently implies the number of leading zero bits but may be changed in the future.
// TODO_MAINNET: Determine if we should launch with a more adaptive difficulty or stick
// to leading zeroes.
func RelayMiningTargetHashToDifficulty(targetHash []byte) int {
numLeadingZeroBits := 0
for _, b := range targetHash {
if b == 0 {
numLeadingZeroBits += 8
continue
} else {
numLeadingZeroBits += bits.LeadingZeros8(b)
break // Stop counting after the first non-zero byte
}
}

return numLeadingZeroBits
}

// LeadingZeroBitsToTargetDifficultyHash generates a slice of bytes with the specified number of leading zero bits
// NB: Exported for testing purposes only.
func LeadingZeroBitsToTargetDifficultyHash(numLeadingZeroBits int, numBytes int) []byte {
Expand Down
8 changes: 4 additions & 4 deletions x/tokenomics/keeper/update_relay_mining_difficulty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestUpdateRelayMiningDifficulty_Base(t *testing.T) {
relaysPerServiceMap := map[string]uint64{
"svc1": 1e3, // new service
}
err := keeper.UpdateRelayMiningDifficulty(ctx, relaysPerServiceMap)
_, err := keeper.UpdateRelayMiningDifficulty(ctx, relaysPerServiceMap)
require.NoError(t, err)

// The first time svc1 difficulty is updated, the relay EMA will be equal
Expand All @@ -40,7 +40,7 @@ func TestUpdateRelayMiningDifficulty_Base(t *testing.T) {
"svc1": 1e10, // higher than the first value above
"svc2": 1e5, // new service
}
err = keeper.UpdateRelayMiningDifficulty(ctx, relaysPerServiceMap)
_, err = keeper.UpdateRelayMiningDifficulty(ctx, relaysPerServiceMap)
require.NoError(t, err)

difficultySvc12, found := keeper.GetRelayMiningDifficulty(ctx, "svc1")
Expand All @@ -65,7 +65,7 @@ func TestUpdateRelayMiningDifficulty_Base(t *testing.T) {
"svc2": 1e2, // lower than the first value above
"svc3": 1e10, // new service
}
err = keeper.UpdateRelayMiningDifficulty(ctx, relaysPerServiceMap)
_, err = keeper.UpdateRelayMiningDifficulty(ctx, relaysPerServiceMap)
require.NoError(t, err)

// svc1 relays went up so the target hash is now a smaller number (more leading zeroes)
Expand Down Expand Up @@ -139,7 +139,7 @@ func TestUpdateRelayMiningDifficulty_FirstDifficulty(t *testing.T) {
relaysPerServiceMap := map[string]uint64{
"svc1": tt.numRelays,
}
err := keeper.UpdateRelayMiningDifficulty(ctx, relaysPerServiceMap)
_, err := keeper.UpdateRelayMiningDifficulty(ctx, relaysPerServiceMap)
require.NoError(t, err)

difficulty, found := keeper.GetRelayMiningDifficulty(ctx, "svc1")
Expand Down
Loading

0 comments on commit 8593170

Please sign in to comment.