Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
_ "cosmossdk.io/x/evidence" // import for side-effects
_ "cosmossdk.io/x/feegrant/module" // import for side-effects
_ "cosmossdk.io/x/upgrade" // import for side-effects
_ "github.com/allora-network/allora-chain/x/emissions/module" // import for side-effects

Check failure on line 54 in app/app.go

View workflow job for this annotation

GitHub Actions / lint

could not import github.com/allora-network/allora-chain/x/emissions/module (-: # github.com/allora-network/allora-chain/x/emissions/module
_ "github.com/allora-network/allora-chain/x/mint/module" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/auth" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
Expand Down Expand Up @@ -255,6 +255,7 @@
if err := app.Load(loadLatest); err != nil {
return nil, err
}
app.Logger().Info("BRYNSK")

return app, nil
}
Expand Down
81 changes: 81 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package errors

import (
"github.com/pkg/errors"

cerrors "cosmossdk.io/errors"
)

type Error = cerrors.Error

var NewCosmos = cerrors.New
var New = errors.New
var WithStack = errors.WithStack
var Errorf = errors.Errorf
var Register = cerrors.Register
var RegisterWithGRPCCode = cerrors.RegisterWithGRPCCode
var Wrap = cerrors.Wrap
var Wrapf = cerrors.Wrapf
var IsOf = cerrors.IsOf
var Is = errors.Is
var Recover = cerrors.Recover
var WithType = cerrors.WithType
var ABCIError = cerrors.ABCIError

const UndefinedCodespace = cerrors.UndefinedCodespace

type ErrorWithFields struct {
fields []any
parent error
}

func NewWithFields(msg string, fields ...any) error {
return WithFields(New(msg), fields...)
}

func WrapWithFields(err error, msg string, fields ...any) error {
return WithFields(Wrap(err, msg), fields...)
}

func WithFields(err error, fields ...any) error {
return &ErrorWithFields{
parent: err,
fields: fields,
}
}

func Annotate(err *error, fields ...any) {
if *err == nil {
return
}
*err = errors.WithStack(*err)
if len(fields) > 0 {
*err = WithFields(*err, fields...)
}
}

func Fields(err error) []any {
var fields []any
for {
errf := &ErrorWithFields{}
if !errors.As(err, &errf) {
break
}
for _, x := range errf.fields {
fields = append(fields, x)
}
err = errf.parent
}
return fields
}

func (ef *ErrorWithFields) Error() string {
if ef.parent != nil {
return ef.parent.Error()
}
return "error with fields"
}

func (ef *ErrorWithFields) Unwrap() error {
return ef.parent
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/allora-network/allora-chain

go 1.22.11
go 1.23

toolchain go1.23.5

Expand Down Expand Up @@ -79,6 +79,7 @@ require (
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
github.com/bits-and-blooms/bitset v1.8.0 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/brynbellomy/go-utils v0.0.0-20250619205733-b48d6fb76e36
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5M
github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/brynbellomy/go-utils v0.0.0-20250619205733-b48d6fb76e36 h1:pMNURzzerKF5mR/8MjMwtGsPvvxWazRkqGRargL8R6Q=
github.com/brynbellomy/go-utils v0.0.0-20250619205733-b48d6fb76e36/go.mod h1:nqSUwdZrKkc5BuR0+5hCwAN6Z8QzyYCFteGXOaYt7Tw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c=
Expand Down
28 changes: 28 additions & 0 deletions utils/fn/fn.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,37 @@
package fn

import "golang.org/x/exp/constraints"

func Map[S []InType, U []OutType, InType any, OutType any](in S, fn func(InType) OutType) U {
out := make([]OutType, len(in))
for i := range in {
out[i] = fn(in[i])
}
return out
}

func Find[S []InType, InType any](in S, fn func(InType) bool) (int, bool) {
for i, item := range in {
if fn(item) {
return i, true
}
}
return 0, false
}

func FilterFn[S []InType, InType any](in S, fn func(InType) bool) S {
out := make(S, 0, len(in))
for _, item := range in {
if fn(item) {
out = append(out, item)
}
}
return out
}

func Trim[S ~[]InType, InType any, I constraints.Integer](in S, n I) S {
if n >= I(len(in)) {
return nil
}
return in[:I(len(in))-n]
}
9 changes: 6 additions & 3 deletions x/emissions/keeper/actor_penalties.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package keeper

import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/allora-network/allora-chain/errors"
alloraMath "github.com/allora-network/allora-chain/math"
"github.com/allora-network/allora-chain/x/emissions/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// ApplyLivenessPenaltyToInferer penalises an inferer for missing previous epochs. It only returns the updated EMA score.
Expand Down Expand Up @@ -74,7 +76,9 @@ func ApplyLivenessPenaltyToActor(
topic types.Topic,
nonceBlockHeight types.BlockHeight,
emaScore types.Score,
) (types.Score, error) {
) (_ types.Score, err error) {
defer errors.Annotate(&err, "topic", topic.Id, "height", nonceBlockHeight, "emaScore", emaScore)

missedEpochs := missedEpochsFn(topic, emaScore.BlockHeight)
// No missed epochs == no penalty
if missedEpochs == 0 {
Expand Down Expand Up @@ -137,6 +141,5 @@ func countContiguousMissedEpochs(prevEpochStart, epochLength, lastSubmittedNonce
if lastSubmittedNonce >= prevEpochStart {
return 0
}

return (prevEpochStart-1-lastSubmittedNonce)/epochLength + 1
}
94 changes: 30 additions & 64 deletions x/emissions/keeper/actor_utils/losses.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package actorutils

import (
"context"
"errors"
"sort"

"cosmossdk.io/collections"
errorsmod "cosmossdk.io/errors"
cosmosMath "cosmossdk.io/math"
"github.com/allora-network/allora-chain/errors"
alloraMath "github.com/allora-network/allora-chain/math"
keeper "github.com/allora-network/allora-chain/x/emissions/keeper"
synth "github.com/allora-network/allora-chain/x/emissions/keeper/inference_synthesis"
Expand All @@ -25,6 +24,8 @@ func CloseReputerNonce(
topic types.Topic,
nonce types.Nonce,
) (err error) {
defer errors.Annotate(&err)

blockHeight := ctx.BlockHeight()

// All filters should be done in order of increasing computational complexity
Expand All @@ -35,7 +36,7 @@ func CloseReputerNonce(
}
// Throw if worker nonce is unfulfilled -- can't report losses on something not yet committed
if workerNonceUnfulfilled {
return errorsmod.Wrapf(
return errors.Wrapf(
types.ErrNonceStillUnfulfilled,
"Reputer's worker nonce not yet fulfilled for reputer block: %v",
&nonce.BlockHeight,
Expand All @@ -49,7 +50,7 @@ func CloseReputerNonce(
}
// Throw if already fulfilled -- can't return a response twice
if !reputerNonceUnfulfilled {
return errorsmod.Wrapf(
return errors.Wrapf(
types.ErrUnfulfilledNonceNotFound,
"Reputer nonce already fulfilled: %v",
&nonce.BlockHeight,
Expand All @@ -60,47 +61,6 @@ func CloseReputerNonce(
return types.ErrReputerNonceWindowNotAvailable
}

defer func() {
if err != nil {
ctx.Logger().Error(
"Error occurred before finalization in CloseReputerNonce, attempting cleanup anyway",
"topicId", topic.Id,
"nonce", nonce,
"error", err,
)
}

_, fulfillErr := k.FulfillReputerNonce(ctx, topic.Id, &nonce)
if fulfillErr != nil {
ctx.Logger().Error(
"Error fulfilling reputer nonce during deferred cleanup",
"topicId", topic.Id,
"nonce", nonce,
"error", fulfillErr,
)
}

resetActiveErr := k.ResetActiveReputersForTopic(ctx, topic.Id)
if resetActiveErr != nil {
ctx.Logger().Error(
"Error resetting active reputers during deferred cleanup",
"topicId", topic.Id,
"error", resetActiveErr,
)
}

resetSubmissionsErr := k.ResetReputersIndividualSubmissionsForTopic(ctx, topic.Id)
if resetSubmissionsErr != nil {
ctx.Logger().Error(
"Error resetting reputer individual submissions during deferred cleanup",
"topicId", topic.Id,
"error", resetSubmissionsErr,
)
}

ctx.Logger().Info("Closed reputer nonce", "topicId", topic.Id, "nonce", nonce)
}()

params, err := k.GetParams(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -148,7 +108,7 @@ func CloseReputerNonce(
}

if len(lossBundlesByReputer) == 0 {
return errorsmod.Wrapf(sdkerrors.ErrNotFound, "no valid losses found for reputers")
return errors.Wrapf(sdkerrors.ErrNotFound, "no valid losses found for reputers")
}

// sort by reputer score descending
Expand Down Expand Up @@ -273,28 +233,32 @@ func CloseReputerNonce(

err = k.SetTopicRewardNonce(ctx, topic.Id, nonce.BlockHeight)
if err != nil {
ctx.Logger().Error(
"Error setting topic reward nonce during deferred cleanup",
"topicId", topic.Id,
"nonceBlockHeight", nonce.BlockHeight,
"error", err,
)
return err
return errors.WrapWithFields(err, "Error setting topic reward nonce", "topicId", topic.Id)
}

err = k.SetReputerTopicLastCommit(ctx, topic.Id, blockHeight, &nonce)
if err != nil {
ctx.Logger().Error(
"Error setting reputer topic last commit during deferred cleanup",
"topicId", topic.Id,
"blockHeight", blockHeight,
"nonce", nonce,
"error", err,
)
return err
return errors.WrapWithFields(err, "Error setting reputer topic last commit", "topicId", topic.Id)
}
types.EmitNewReputerLastCommitSetEvent(ctx, topic.Id, blockHeight, &nonce)

_, err = k.FulfillReputerNonce(ctx, topic.Id, &nonce)
if err != nil {
return errors.WrapWithFields(err, "Error fulfilling reputer nonce", "topicId", topic.Id)
}

err = k.ResetActiveReputersForTopic(ctx, topic.Id)
if err != nil {
return errors.WrapWithFields(err, "Error resetting active reputers for topic", "topicId", topic.Id)
}

err = k.ResetReputersIndividualSubmissionsForTopic(ctx, topic.Id)
if err != nil {
return errors.WrapWithFields(err, "Error resetting reputer individual submissions", "topicId", topic.Id)
}

ctx.Logger().Info("Closed reputer nonce", "topicId", topic.Id, "nonce", nonce)

return nil
}

Expand All @@ -307,11 +271,13 @@ func FilterUnacceptedWorkersFromReputerValueBundle(
topicId uint64,
reputerRequestNonce types.ReputerRequestNonce,
reputerValueBundle *types.ReputerValueBundle,
) (*types.ReputerValueBundle, error) {
) (_ *types.ReputerValueBundle, err error) {
defer errors.Annotate(&err)

// Get the accepted inferers of the associated worker response payload
inferences, err := k.GetInferencesAtBlock(ctx, topicId, reputerRequestNonce.ReputerNonce.BlockHeight, false)
if errors.Is(err, collections.ErrNotFound) {
return nil, errorsmod.Wrapf(sdkerrors.ErrNotFound, "no inferences found at block height %d for topic %d", reputerRequestNonce.ReputerNonce.BlockHeight, topicId)
return nil, errors.Wrapf(sdkerrors.ErrNotFound, "no inferences found at block height %d for topic %d", reputerRequestNonce.ReputerNonce.BlockHeight, topicId)
} else if err != nil {
return nil, err
}
Expand Down Expand Up @@ -434,7 +400,7 @@ func FilterUnacceptedWorkersFromReputerValueBundle(
// e.g., if CalcNetworkLosses requires at least one value. Add checks if necessary.

if len(acceptedInfererValues) == 0 {
return nil, errorsmod.Wrapf(sdkerrors.ErrNotFound, "no valid values found after filtering")
return nil, errors.Wrapf(sdkerrors.ErrNotFound, "no valid values found after filtering")
}

acceptedReputerValueBundle := &types.ReputerValueBundle{
Expand Down
Loading
Loading