-
Notifications
You must be signed in to change notification settings - Fork 131
Generic labels in metrics, usage in events and q/tx #816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
43f8b82
9e84758
b8f6155
cf48071
ceb3241
c6dc8f0
b3d8488
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,22 @@ | ||
| Emissions Module | ||
| ============================================= | ||
|
|
||
| ## Dependencies | ||
| The `emissions` module is a core component of the Allora Network that manages the topic definition, actor participation, economic incentives, rewards system and more. This is the main part of the implementation of the [Allora Whitepaper](https://research.assets.allora.network/allora.0x10001.pdf). | ||
|
|
||
| golang v1.21+ | ||
| GNU make | ||
| docker | ||
| Key Features: | ||
| - Topic Management: Creation and management of prediction topics | ||
| - Stake Management: Handling of stakes for workers and reputers | ||
| - Reward Distribution: Calculation and distribution of rewards based on performance | ||
| - Delegation System: Support for stake delegation to reputers | ||
| - Performance Metrics: Tracking of worker, reputer, and forecaster scores | ||
| - Fee Collection: Management of network fees and revenue distribution | ||
|
|
||
| ## Build | ||
| ```bash | ||
| # get deps | ||
| go mod tidy | ||
|
|
||
| # rebuild the autogenerated protobuf files | ||
| make proto-all | ||
| ## Monitoring | ||
|
|
||
| # build the module, making sure the source compiles | ||
| make | ||
| ``` | ||
| Allora node emits its own `emissions` module metrics in each event, query and tx. | ||
| event: `allora_loadtest_produce_count` | ||
| query/tx: `allora_request_counter` for occurrences, `allora_request_latency_ms` for latency measures. | ||
| Different labels are applied where appropriate (eg "topic_id", "address", "nonce", etc.) | ||
| See `x/emissions/metrics/` for details. | ||
|
|
||
| Then somewhere else you have a minimal-chain running: | ||
| ```bash | ||
| cd ../minimal-chain | ||
| go mod tidy | ||
| make install | ||
| make init | ||
| allorad start | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ package msgserver | |
|
|
||
| import ( | ||
| "context" | ||
| "strconv" | ||
| "time" | ||
|
|
||
| errorsmod "cosmossdk.io/errors" | ||
|
|
@@ -14,27 +15,54 @@ import ( | |
|
|
||
| // A tx function that accepts a individual loss and possibly returns an error | ||
| func (ms msgServer) InsertReputerPayload(ctx context.Context, msg *types.InsertReputerPayloadRequest) (_ *types.InsertReputerPayloadResponse, err error) { | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err) | ||
|
|
||
| sdkCtx := sdk.UnwrapSDKContext(ctx) | ||
| blockHeight := sdkCtx.BlockHeight() | ||
|
|
||
| moduleParams, err := ms.k.GetParams(ctx) | ||
| if err != nil { | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err, map[string]string{"error": err.Error()}) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having error messages as label can creates a lot of metric entries and are hard to use (e.g. error msgs can contains values creating multiple error labels for the same one), it's preferable to use error codes instead |
||
| return nil, errorsmod.Wrapf(err, "Error getting params for reputer: %v", &msg.ReputerValueBundle.ValueBundle.Reputer) | ||
| } | ||
| err = ms.k.ValidateStringIsBech32(msg.Sender) | ||
| if err != nil { | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err, map[string]string{"error": err.Error()}) | ||
| return nil, errorsmod.Wrapf(err, "Error validating sender address") | ||
| } | ||
| // fast permission check before entering validations which are more expensive | ||
| if msg.ReputerValueBundle != nil && msg.ReputerValueBundle.ValueBundle != nil { | ||
| err = ms.k.ValidateStringIsBech32(msg.ReputerValueBundle.ValueBundle.Reputer) | ||
| if err != nil { | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err, map[string]string{"error": err.Error()}) | ||
| return nil, errorsmod.Wrapf(err, "Error validating reputer address") | ||
| } | ||
| canSubmit, err := ms.k.CanSubmitReputerPayload(ctx, msg.ReputerValueBundle.ValueBundle.TopicId, msg.ReputerValueBundle.ValueBundle.Reputer) | ||
| if err != nil { | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err, map[string]string{"error": err.Error()}) | ||
| return nil, err | ||
| } else if !canSubmit { | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err, map[string]string{"error": types.ErrNotPermittedToSubmitReputerPayload.Error()}) | ||
| return nil, types.ErrNotPermittedToSubmitReputerPayload | ||
| } | ||
| } else { | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err, map[string]string{"error": types.ErrInvalidReputerData.Error()}) | ||
| return nil, types.ErrInvalidReputerData | ||
| } | ||
|
|
||
| // includes validation | ||
| rvb, err := types.NewInputReputerValueBundleFromInput(msg.ReputerValueBundle) | ||
| if err != nil { | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err, map[string]string{"error": err.Error()}) | ||
| return nil, errorsmod.Wrapf(err, | ||
| "Reputer bad data format for block: %d", blockHeight) | ||
| } | ||
|
|
||
| canSubmit, err := ms.k.CanSubmitReputerPayload(ctx, rvb.ValueBundle.TopicId, rvb.ValueBundle.Reputer) | ||
| if err != nil { | ||
| return nil, err | ||
| } else if !canSubmit { | ||
| return nil, types.ErrNotPermittedToSubmitReputerPayload | ||
| // if validated, record metrics with appropriate labels | ||
| labels := map[string]string{ | ||
| "address": msg.ReputerValueBundle.ValueBundle.Reputer, | ||
| "topic_id": strconv.FormatUint(msg.ReputerValueBundle.ValueBundle.TopicId, 10), | ||
| "nonce": strconv.FormatUint(uint64(msg.ReputerValueBundle.ValueBundle.ReputerRequestNonce.ReputerNonce.BlockHeight), 10), | ||
| "blockHeight": strconv.FormatInt(blockHeight, 10), | ||
| } | ||
| defer metrics.RecordMetrics("InsertReputerPayload", time.Now(), &err, labels) | ||
|
Comment on lines
+59
to
+65
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have multiple remarks here:
I think we should have only one |
||
|
|
||
| err = checkInputLength(moduleParams.MaxSerializedMsgLength, msg) | ||
| if err != nil { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should avoid labels with high cardinality, I think setting
addressas label would create too much metric entries which can impacts node performance