diff --git a/x/oracle/abci.go b/x/oracle/abci.go index d04b68ec..73dff49d 100644 --- a/x/oracle/abci.go +++ b/x/oracle/abci.go @@ -54,8 +54,9 @@ func CalcPrices(ctx sdk.Context, params types.Params, k keeper.Keeper) error { // Iterate through ballots and update exchange rates; drop if not enough votes have been achieved. for _, ballotDenom := range ballotDenomSlice { + // Convert ballot power to a percentage to compare with VoteThreshold param if sdk.NewDecWithPrec(ballotDenom.Ballot.Power(), 2).LTE(k.VoteThreshold(ctx)) { - ctx.Logger().Info("Ballot voting power is under vote threshold, dropping ballot for", ballotDenom) + ctx.Logger().Info("Ballot voting power is under vote threshold, dropping ballot", "denom", ballotDenom) continue } diff --git a/x/oracle/abci_test.go b/x/oracle/abci_test.go index 86bc0c30..9e3897d9 100644 --- a/x/oracle/abci_test.go +++ b/x/oracle/abci_test.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/teststaking" @@ -23,10 +22,8 @@ import ( ) const ( - displayDenom string = appparams.DisplayDenom - bondDenom string = appparams.BondDenom - preVoteBlockDiff int64 = 2 - voteBlockDiff int64 = 3 + displayDenom string = appparams.DisplayDenom + bondDenom string = appparams.BondDenom ) type IntegrationTestSuite struct { @@ -93,7 +90,9 @@ var ( func (s *IntegrationTestSuite) TestEndBlockerVoteThreshold() { app, ctx := s.app, s.ctx originalBlockHeight := ctx.BlockHeight() - ctx = ctx.WithBlockHeight(6) + ctx = ctx.WithBlockHeight(1) + preVoteBlockDiff := int64(app.OracleKeeper.VotePeriod(ctx) / 2) + voteBlockDiff := int64(app.OracleKeeper.VotePeriod(ctx)/2 + 1) var ( val1DecCoins sdk.DecCoins @@ -165,7 +164,7 @@ func (s *IntegrationTestSuite) TestEndBlockerVoteThreshold() { for _, denom := range app.OracleKeeper.AcceptList(ctx) { rate, err := app.OracleKeeper.GetExchangeRate(ctx, denom.SymbolDenom) - s.Require().ErrorIs(err, sdkerrors.Wrap(types.ErrUnknownDenom, denom.SymbolDenom)) + s.Require().ErrorIs(err, types.ErrUnknownDenom.Wrap(denom.SymbolDenom)) s.Require().Equal(sdk.ZeroDec(), rate) } @@ -207,7 +206,7 @@ func (s *IntegrationTestSuite) TestEndBlockerVoteThreshold() { s.Require().NoError(err) s.Require().Equal(sdk.MustNewDecFromStr("0.75"), rate) rate, err = app.OracleKeeper.GetExchangeRate(ctx, "atom") - s.Require().ErrorIs(err, sdkerrors.Wrap(types.ErrUnknownDenom, "atom")) + s.Require().ErrorIs(err, types.ErrUnknownDenom.Wrap("atom")) s.Require().Equal(sdk.ZeroDec(), rate) ctx = ctx.WithBlockHeight(originalBlockHeight) @@ -216,7 +215,9 @@ func (s *IntegrationTestSuite) TestEndBlockerVoteThreshold() { func (s *IntegrationTestSuite) TestEndBlockerValidatorRewards() { app, ctx := s.app, s.ctx originalBlockHeight := ctx.BlockHeight() - ctx = ctx.WithBlockHeight(6) + ctx = ctx.WithBlockHeight(1) + preVoteBlockDiff := int64(app.OracleKeeper.VotePeriod(ctx) / 2) + voteBlockDiff := int64(app.OracleKeeper.VotePeriod(ctx)/2 + 1) app.OracleKeeper.SetMandatoryList(ctx, types.DenomList{ { diff --git a/x/oracle/keeper/historic_price.go b/x/oracle/keeper/historic_price.go index d1bb83ea..625e3890 100644 --- a/x/oracle/keeper/historic_price.go +++ b/x/oracle/keeper/historic_price.go @@ -1,10 +1,8 @@ package keeper import ( - "fmt" - + "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/ojo-network/ojo/util/decmath" "github.com/ojo-network/ojo/x/oracle/types" @@ -38,7 +36,7 @@ func (k Keeper) CalcAndSetHistoricMedian( historicPrices := k.historicPrices(ctx, denom, k.MaximumPriceStamps(ctx)) median, err := decmath.Median(historicPrices) if err != nil { - return sdkerrors.Wrap(err, fmt.Sprintf("denom: %s", denom)) + return errors.Wrap(err, "denom: "+denom) } block := uint64(ctx.BlockHeight()) @@ -68,7 +66,7 @@ func (k Keeper) HistoricMedianDeviation( blockDiff := uint64(ctx.BlockHeight())%k.MedianStampPeriod(ctx) + 1 bz := store.Get(types.KeyMedianDeviation(denom, uint64(ctx.BlockHeight())-blockDiff)) if bz == nil { - return sdk.ZeroDec(), sdkerrors.Wrap(types.ErrNoMedianDeviation, fmt.Sprintf("denom: %s", denom)) + return sdk.ZeroDec(), types.ErrNoMedianDeviation.Wrap("denom: " + denom) } decProto := sdk.DecProto{} @@ -87,14 +85,14 @@ func (k Keeper) WithinHistoricMedianDeviation( // get latest median medians := k.HistoricMedians(ctx, denom, 1) if len(medians) == 0 { - return false, sdkerrors.Wrap(types.ErrNoMedian, fmt.Sprintf("denom: %s", denom)) + return false, types.ErrNoMedian.Wrap("denom: " + denom) } median := medians[0] // get latest historic price prices := k.historicPrices(ctx, denom, 1) if len(prices) == 0 { - return false, sdkerrors.Wrap(types.ErrNoHistoricPrice, fmt.Sprintf("denom: %s", denom)) + return false, types.ErrNoHistoricPrice.Wrap("denom: " + denom) } price := prices[0] @@ -116,7 +114,7 @@ func (k Keeper) calcAndSetHistoricMedianDeviation( ) error { medianDeviation, err := decmath.MedianDeviation(median, prices) if err != nil { - return sdkerrors.Wrap(err, fmt.Sprintf("denom: %s", denom)) + return errors.Wrap(err, "denom: "+denom) } block := uint64(ctx.BlockHeight()) @@ -149,7 +147,7 @@ func (k Keeper) MedianOfHistoricMedians( } median, err := decmath.Median(medians) if err != nil { - return sdk.ZeroDec(), 0, sdkerrors.Wrap(err, fmt.Sprintf("denom: %s", denom)) + return sdk.ZeroDec(), 0, errors.Wrap(err, "denom: "+denom) } return median, uint32(len(medians)), nil @@ -169,7 +167,7 @@ func (k Keeper) AverageOfHistoricMedians( } average, err := decmath.Average(medians) if err != nil { - return sdk.ZeroDec(), 0, sdkerrors.Wrap(err, fmt.Sprintf("denom: %s", denom)) + return sdk.ZeroDec(), 0, errors.Wrap(err, "denom: "+denom) } return average, uint32(len(medians)), nil @@ -189,7 +187,7 @@ func (k Keeper) MaxOfHistoricMedians( } max, err := decmath.Max(medians) if err != nil { - return sdk.ZeroDec(), 0, sdkerrors.Wrap(err, fmt.Sprintf("denom: %s", denom)) + return sdk.ZeroDec(), 0, errors.Wrap(err, "denom: "+denom) } return max, uint32(len(medians)), nil @@ -209,7 +207,7 @@ func (k Keeper) MinOfHistoricMedians( } min, err := decmath.Min(medians) if err != nil { - return sdk.ZeroDec(), 0, sdkerrors.Wrap(err, fmt.Sprintf("denom: %s", denom)) + return sdk.ZeroDec(), 0, errors.Wrap(err, "denom: "+denom) } return min, uint32(len(medians)), nil diff --git a/x/oracle/keeper/keeper.go b/x/oracle/keeper/keeper.go index 3008d118..c9e96f6f 100644 --- a/x/oracle/keeper/keeper.go +++ b/x/oracle/keeper/keeper.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/tendermint/tendermint/libs/log" @@ -76,7 +75,7 @@ func (k Keeper) GetExchangeRate(ctx sdk.Context, symbol string) (sdk.Dec, error) symbol = strings.ToUpper(symbol) b := store.Get(types.GetExchangeRateKey(symbol)) if b == nil { - return sdk.ZeroDec(), sdkerrors.Wrap(types.ErrUnknownDenom, symbol) + return sdk.ZeroDec(), types.ErrUnknownDenom.Wrap(symbol) } decProto := sdk.DecProto{} @@ -100,7 +99,7 @@ func (k Keeper) GetExchangeRateBase(ctx sdk.Context, denom string) (sdk.Dec, err } } if len(symbol) == 0 { - return sdk.ZeroDec(), sdkerrors.Wrap(types.ErrUnknownDenom, denom) + return sdk.ZeroDec(), types.ErrUnknownDenom.Wrap(denom) } exchangeRate, err := k.GetExchangeRate(ctx, symbol) @@ -211,7 +210,7 @@ func (k Keeper) GetAggregateExchangeRatePrevote( bz := store.Get(types.GetAggregateExchangeRatePrevoteKey(voter)) if bz == nil { - return types.AggregateExchangeRatePrevote{}, sdkerrors.Wrap(types.ErrNoAggregatePrevote, voter.String()) + return types.AggregateExchangeRatePrevote{}, types.ErrNoAggregatePrevote.Wrap(voter.String()) } var aggregatePrevote types.AggregateExchangeRatePrevote @@ -278,7 +277,7 @@ func (k Keeper) GetAggregateExchangeRateVote( bz := store.Get(types.GetAggregateExchangeRateVoteKey(voter)) if bz == nil { - return types.AggregateExchangeRateVote{}, sdkerrors.Wrap(types.ErrNoAggregateVote, voter.String()) + return types.AggregateExchangeRateVote{}, types.ErrNoAggregateVote.Wrap(voter.String()) } var aggregateVote types.AggregateExchangeRateVote @@ -339,7 +338,7 @@ func (k Keeper) ValidateFeeder(ctx sdk.Context, feederAddr sdk.AccAddress, valAd return err } if !delegate.Equals(feederAddr) { - return sdkerrors.Wrap(types.ErrNoVotingPermission, feederAddr.String()) + return types.ErrNoVotingPermission.Wrap(feederAddr.String()) } return nil diff --git a/x/oracle/keeper/msg_server.go b/x/oracle/keeper/msg_server.go index fe46ddc0..ad6bd900 100644 --- a/x/oracle/keeper/msg_server.go +++ b/x/oracle/keeper/msg_server.go @@ -4,7 +4,6 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/ojo-network/ojo/x/oracle/types" @@ -46,7 +45,7 @@ func (ms msgServer) AggregateExchangeRatePrevote( // Convert hex string to votehash voteHash, err := types.AggregateVoteHashFromHexString(msg.Hash) if err != nil { - return nil, sdkerrors.Wrap(types.ErrInvalidHash, err.Error()) + return nil, types.ErrInvalidHash.Wrap(err.Error()) } aggregatePrevote := types.NewAggregateExchangeRatePrevote(voteHash, valAddr, uint64(ctx.BlockHeight())) @@ -75,7 +74,7 @@ func (ms msgServer) AggregateExchangeRateVote( params := ms.GetParams(ctx) aggregatePrevote, err := ms.GetAggregateExchangeRatePrevote(ctx, valAddr) if err != nil { - return nil, sdkerrors.Wrap(types.ErrNoAggregatePrevote, msg.Validator) + return nil, types.ErrNoAggregatePrevote.Wrap(msg.Validator) } // Check a msg is submitted proper period @@ -85,13 +84,13 @@ func (ms msgServer) AggregateExchangeRateVote( exchangeRates, err := types.ParseExchangeRateDecCoins(msg.ExchangeRates) if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, err.Error()) + return nil, types.ErrInvalidExchangeRate.Wrap(err.Error()) } // Verify a exchange rate with aggregate prevote hash hash := types.GetAggregateVoteHash(msg.Salt, msg.ExchangeRates, valAddr) if aggregatePrevote.Hash != hash.String() { - return nil, sdkerrors.Wrapf(types.ErrVerificationFailed, "must be given %s not %s", aggregatePrevote.Hash, hash) + return nil, types.ErrVerificationFailed.Wrapf("must be given %s not %s", aggregatePrevote.Hash, hash) } // Filter out rates which aren't included in the AcceptList @@ -127,7 +126,7 @@ func (ms msgServer) DelegateFeedConsent( val := ms.StakingKeeper.Validator(ctx, operatorAddr) if val == nil { - return nil, sdkerrors.Wrap(stakingtypes.ErrNoValidatorFound, msg.Operator) + return nil, stakingtypes.ErrNoValidatorFound.Wrap(msg.Operator) } ms.SetFeederDelegation(ctx, operatorAddr, delegateAddr) diff --git a/x/oracle/types/errors.go b/x/oracle/types/errors.go index a8cb9390..3dd1d220 100644 --- a/x/oracle/types/errors.go +++ b/x/oracle/types/errors.go @@ -3,30 +3,30 @@ package types import ( "fmt" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "cosmossdk.io/errors" "github.com/tendermint/tendermint/crypto/tmhash" ) // Oracle sentinel errors var ( - ErrInvalidExchangeRate = sdkerrors.Register(ModuleName, 1, "invalid exchange rate") - ErrNoPrevote = sdkerrors.Register(ModuleName, 2, "no prevote") - ErrNoVote = sdkerrors.Register(ModuleName, 3, "no vote") - ErrNoVotingPermission = sdkerrors.Register(ModuleName, 4, "unauthorized voter") - ErrInvalidHash = sdkerrors.Register(ModuleName, 5, "invalid hash") - ErrInvalidHashLength = sdkerrors.Register(ModuleName, 6, fmt.Sprintf("invalid hash length; should equal %d", tmhash.TruncatedSize)) //nolint: lll - ErrVerificationFailed = sdkerrors.Register(ModuleName, 7, "hash verification failed") - ErrRevealPeriodMissMatch = sdkerrors.Register(ModuleName, 8, "reveal period of submitted vote does not match with registered prevote") //nolint: lll - ErrInvalidSaltLength = sdkerrors.Register(ModuleName, 9, "invalid salt length; must be 64") - ErrInvalidSaltFormat = sdkerrors.Register(ModuleName, 10, "invalid salt format") - ErrNoAggregatePrevote = sdkerrors.Register(ModuleName, 11, "no aggregate prevote") - ErrNoAggregateVote = sdkerrors.Register(ModuleName, 12, "no aggregate vote") - ErrUnknownDenom = sdkerrors.Register(ModuleName, 13, "unknown denom") - ErrNegativeOrZeroRate = sdkerrors.Register(ModuleName, 14, "invalid exchange rate; should be positive") - ErrExistingPrevote = sdkerrors.Register(ModuleName, 15, "prevote already submitted for this voting period") - ErrBallotNotSorted = sdkerrors.Register(ModuleName, 16, "ballot must be sorted before this operation") - ErrInvalidOraclePrice = sdkerrors.Register(ModuleName, 17, "invalid or unavailable oracle price") - ErrNoHistoricPrice = sdkerrors.Register(ModuleName, 18, "no historic price for this denom at this block") - ErrNoMedian = sdkerrors.Register(ModuleName, 19, "no median for this denom at this block") - ErrNoMedianDeviation = sdkerrors.Register(ModuleName, 20, "no median deviation for this denom at this block") + ErrInvalidExchangeRate = errors.Register(ModuleName, 2, "invalid exchange rate") + ErrNoPrevote = errors.Register(ModuleName, 3, "no prevote") + ErrNoVote = errors.Register(ModuleName, 4, "no vote") + ErrNoVotingPermission = errors.Register(ModuleName, 5, "unauthorized voter") + ErrInvalidHash = errors.Register(ModuleName, 6, "invalid hash") + ErrInvalidHashLength = errors.Register(ModuleName, 7, fmt.Sprintf("invalid hash length; should equal %d", tmhash.TruncatedSize)) //nolint: lll + ErrVerificationFailed = errors.Register(ModuleName, 8, "hash verification failed") + ErrRevealPeriodMissMatch = errors.Register(ModuleName, 9, "reveal period of submitted vote does not match with registered prevote") //nolint: lll + ErrInvalidSaltLength = errors.Register(ModuleName, 10, "invalid salt length; must be 64") + ErrInvalidSaltFormat = errors.Register(ModuleName, 11, "invalid salt format") + ErrNoAggregatePrevote = errors.Register(ModuleName, 12, "no aggregate prevote") + ErrNoAggregateVote = errors.Register(ModuleName, 13, "no aggregate vote") + ErrUnknownDenom = errors.Register(ModuleName, 14, "unknown denom") + ErrNegativeOrZeroRate = errors.Register(ModuleName, 15, "invalid exchange rate; should be positive") + ErrExistingPrevote = errors.Register(ModuleName, 16, "prevote already submitted for this voting period") + ErrBallotNotSorted = errors.Register(ModuleName, 17, "ballot must be sorted before this operation") + ErrInvalidOraclePrice = errors.Register(ModuleName, 18, "invalid or unavailable oracle price") + ErrNoHistoricPrice = errors.Register(ModuleName, 19, "no historic price for this denom at this block") + ErrNoMedian = errors.Register(ModuleName, 20, "no median for this denom at this block") + ErrNoMedianDeviation = errors.Register(ModuleName, 21, "no median deviation for this denom at this block") ) diff --git a/x/oracle/types/msgs.go b/x/oracle/types/msgs.go index b83ddf17..f1b58dc2 100644 --- a/x/oracle/types/msgs.go +++ b/x/oracle/types/msgs.go @@ -43,7 +43,7 @@ func (msg MsgAggregateExchangeRatePrevote) GetSigners() []sdk.AccAddress { func (msg MsgAggregateExchangeRatePrevote) ValidateBasic() error { _, err := AggregateVoteHashFromHexString(msg.Hash) if err != nil { - return sdkerrors.Wrapf(ErrInvalidHash, "invalid vote hash (%s)", err) + return ErrInvalidHash.Wrapf("invalid vote hash (%s)", err) } // HEX encoding doubles the hash length @@ -53,12 +53,12 @@ func (msg MsgAggregateExchangeRatePrevote) ValidateBasic() error { _, err = sdk.AccAddressFromBech32(msg.Feeder) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid feeder address (%s)", err) + return sdkerrors.ErrInvalidAddress.Wrapf("invalid feeder address (%s)", err) } _, err = sdk.ValAddressFromBech32(msg.Validator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid operator address (%s)", err) + return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address (%s)", err) } return nil @@ -95,29 +95,29 @@ func (msg MsgAggregateExchangeRateVote) GetSigners() []sdk.AccAddress { func (msg MsgAggregateExchangeRateVote) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Feeder) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid feeder address (%s)", err) + return sdkerrors.ErrInvalidAddress.Wrapf("invalid feeder address (%s)", err) } _, err = sdk.ValAddressFromBech32(msg.Validator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid operator address (%s)", err) + return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address (%s)", err) } if l := len(msg.ExchangeRates); l == 0 { - return sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "must provide at least one oracle exchange rate") + return sdkerrors.ErrInvalidRequest.Wrap("must provide at least one oracle exchange rate") } else if l > 4096 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "exchange rates string can not exceed 4096 characters") + return sdkerrors.ErrInvalidRequest.Wrap("exchange rates string can not exceed 4096 characters") } exchangeRates, err := ParseExchangeRateDecCoins(msg.ExchangeRates) if err != nil { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "failed to parse exchange rates string cause: "+err.Error()) + return sdkerrors.ErrInvalidCoins.Wrap("failed to parse exchange rates string cause: " + err.Error()) } for _, exchangeRate := range exchangeRates { // check overflow bit length if exchangeRate.Amount.BigInt().BitLen() > 255+sdk.DecimalPrecisionBits { - return sdkerrors.Wrap(ErrInvalidExchangeRate, "overflow") + return ErrInvalidExchangeRate.Wrap("overflow") } } @@ -126,7 +126,7 @@ func (msg MsgAggregateExchangeRateVote) ValidateBasic() error { } _, err = AggregateVoteHashFromHexString(msg.Salt) if err != nil { - return sdkerrors.Wrap(ErrInvalidSaltFormat, "salt must be a valid hex string") + return ErrInvalidSaltFormat.Wrap("salt must be a valid hex string") } return nil @@ -158,12 +158,12 @@ func (msg MsgDelegateFeedConsent) GetSigners() []sdk.AccAddress { func (msg MsgDelegateFeedConsent) ValidateBasic() error { _, err := sdk.ValAddressFromBech32(msg.Operator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid operator address (%s)", err) + return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address (%s)", err) } _, err = sdk.AccAddressFromBech32(msg.Delegate) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid delegate address (%s)", err) + return sdkerrors.ErrInvalidAddress.Wrapf("invalid delegate address (%s)", err) } return nil diff --git a/x/oracle/types/msgs_test.go b/x/oracle/types/msgs_test.go index 7a5a5202..c921135a 100644 --- a/x/oracle/types/msgs_test.go +++ b/x/oracle/types/msgs_test.go @@ -91,7 +91,7 @@ func TestMsgAggregateExchangeRateVote(t *testing.T) { msgInvalidSalt := "invalid salt length; must be 64" msgInvalidOverflowValue := "out of range; bitLen:" msgInvalidHexString := "salt must be a valid hex string: invalid salt format" - msgInvalidUnknownRequest := "must provide at least one oracle exchange rate: unknown request" + msgInvalidUnknownRequest := "must provide at least one oracle exchange rate: invalid request" msgInvalidFeederAddr := "invalid feeder address (empty address string is not allowed): invalid address" msgInvalidOperatorAddr := "invalid operator address (empty address string is not allowed): invalid address" msgInvalidOraclePrice := "oracle price"