Skip to content

Commit 5715506

Browse files
committed
feat: node gigabyte_prices and hourly_prices should only contain the allowed denoms
1 parent 8ee49a9 commit 5715506

File tree

4 files changed

+80
-60
lines changed

4 files changed

+80
-60
lines changed

types/v1/price.go

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ func (p Prices) Copy() Prices {
302302

303303
// String converts the Prices slice to a semicolon-separated string.
304304
func (p Prices) String() string {
305-
var parts []string
305+
parts := make([]string, 0, len(p))
306306
for _, price := range p {
307307
parts = append(parts, price.String())
308308
}
@@ -410,6 +410,36 @@ func (p Prices) Find(denom string) (Price, bool) {
410410
return Price{}, false
411411
}
412412

413+
// Add adds multiple Price values to the Prices slice.
414+
func (p Prices) Add(items ...Price) Prices {
415+
return p.add(items)
416+
}
417+
418+
// Sub subtracts multiple Price values from the Prices slice.
419+
func (p Prices) Sub(items ...Price) Prices {
420+
return p.sub(items)
421+
}
422+
423+
// Map converts the Prices slice into a map[denom]Price.
424+
// Panics if a duplicate denom exists in the result.
425+
func (p Prices) Map() map[string]Price {
426+
m := make(map[string]Price, len(p))
427+
for _, price := range p {
428+
if _, exists := m[price.Denom]; exists {
429+
panic(fmt.Errorf("duplicate denom %s", price.Denom))
430+
}
431+
432+
m[price.Denom] = price
433+
}
434+
435+
return m
436+
}
437+
438+
// add adds values of another Prices slice to this one.
439+
func (p Prices) add(v Prices) Prices {
440+
return p.merge(v)
441+
}
442+
413443
// merge merges and sums two Prices slices by denom.
414444
func (p Prices) merge(v Prices) Prices {
415445
m := make(map[string]Price)
@@ -444,22 +474,7 @@ func (p Prices) negative() Prices {
444474
return v
445475
}
446476

447-
// add adds values of another Prices slice to this one.
448-
func (p Prices) add(v Prices) Prices {
449-
return p.merge(v)
450-
}
451-
452-
// Add adds multiple Price values to the Prices slice.
453-
func (p Prices) Add(items ...Price) Prices {
454-
return p.add(items)
455-
}
456-
457477
// sub subtracts values of another Prices slice from this one.
458478
func (p Prices) sub(v Prices) Prices {
459479
return p.merge(v.negative())
460480
}
461-
462-
// Sub subtracts multiple Price values from the Prices slice.
463-
func (p Prices) Sub(items ...Price) Prices {
464-
return p.sub(items)
465-
}

x/node/keeper/msg_handler.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ import (
1717
// It validates the pricing fields, checks for duplicates, collects deposit, and stores the new node in an inactive state.
1818
func (k *Keeper) HandleMsgRegisterNode(ctx sdk.Context, msg *v3.MsgRegisterNodeRequest) (*v3.MsgRegisterNodeResponse, error) {
1919
// Validate submitted gigabyte prices
20-
if !k.IsValidGigabytePrices(ctx, msg.GigabytePrices) {
21-
return nil, types.NewErrorInvalidPrices(msg.GigabytePrices)
20+
if err := k.ValidateGigabytePrices(ctx, msg.GigabytePrices); err != nil {
21+
return nil, types.NewErrorInvalidPrices(err)
2222
}
2323

2424
// Validate submitted hourly prices
25-
if !k.IsValidHourlyPrices(ctx, msg.HourlyPrices) {
26-
return nil, types.NewErrorInvalidPrices(msg.HourlyPrices)
25+
if err := k.ValidateHourlyPrices(ctx, msg.HourlyPrices); err != nil {
26+
return nil, types.NewErrorInvalidPrices(err)
2727
}
2828

2929
// Parse the account address from the sender string
@@ -78,13 +78,13 @@ func (k *Keeper) HandleMsgRegisterNode(ctx sdk.Context, msg *v3.MsgRegisterNodeR
7878
// It verifies node existence and applies new pricing and metadata, emitting an update event.
7979
func (k *Keeper) HandleMsgUpdateNodeDetails(ctx sdk.Context, msg *v3.MsgUpdateNodeDetailsRequest) (*v3.MsgUpdateNodeDetailsResponse, error) {
8080
// Validate new gigabyte prices
81-
if !k.IsValidGigabytePrices(ctx, msg.GigabytePrices) {
82-
return nil, types.NewErrorInvalidPrices(msg.GigabytePrices)
81+
if err := k.ValidateGigabytePrices(ctx, msg.GigabytePrices); err != nil {
82+
return nil, types.NewErrorInvalidPrices(err)
8383
}
8484

8585
// Validate new hourly prices
86-
if !k.IsValidHourlyPrices(ctx, msg.HourlyPrices) {
87-
return nil, types.NewErrorInvalidPrices(msg.HourlyPrices)
86+
if err := k.ValidateHourlyPrices(ctx, msg.HourlyPrices); err != nil {
87+
return nil, types.NewErrorInvalidPrices(err)
8888
}
8989

9090
// Parse sender's node address

x/node/keeper/params.go

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package keeper
22

33
import (
4+
"fmt"
45
"time"
56

67
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -50,46 +51,18 @@ func (k *Keeper) MinHourlyPrices(ctx sdk.Context) v1base.Prices {
5051
return k.GetParams(ctx).MinHourlyPrices
5152
}
5253

53-
// IsValidGigabytePrices checks if the provided gigabyte prices are valid based on the minimum prices defined in the module's parameters.
54-
func (k *Keeper) IsValidGigabytePrices(ctx sdk.Context, prices v1base.Prices) bool {
55-
if prices.Len() == 0 {
56-
return true
57-
}
58-
54+
// ValidateGigabytePrices validates prices against the minimum gigabyte prices.
55+
func (k *Keeper) ValidateGigabytePrices(ctx sdk.Context, prices v1base.Prices) error {
5956
minPrices := k.MinGigabytePrices(ctx)
60-
for _, price := range minPrices {
61-
baseValue, quoteValue := prices.AmountOf(price.Denom)
62-
if !baseValue.IsZero() && baseValue.LT(price.BaseValue) {
63-
return false
64-
}
65-
66-
if !quoteValue.IsZero() && quoteValue.LT(price.QuoteValue) {
67-
return false
68-
}
69-
}
7057

71-
return true
58+
return validatePrices(prices, minPrices)
7259
}
7360

74-
// IsValidHourlyPrices checks if the provided hourly prices are valid based on the minimum prices defined in the module's parameters.
75-
func (k *Keeper) IsValidHourlyPrices(ctx sdk.Context, prices v1base.Prices) bool {
76-
if prices.Len() == 0 {
77-
return true
78-
}
79-
61+
// ValidateHourlyPrices validates prices against the minimum hourly prices.
62+
func (k *Keeper) ValidateHourlyPrices(ctx sdk.Context, prices v1base.Prices) error {
8063
minPrices := k.MinHourlyPrices(ctx)
81-
for _, price := range minPrices {
82-
baseValue, quoteValue := prices.AmountOf(price.Denom)
83-
if !baseValue.IsZero() && baseValue.LT(price.BaseValue) {
84-
return false
85-
}
86-
87-
if !quoteValue.IsZero() && quoteValue.LT(price.QuoteValue) {
88-
return false
89-
}
90-
}
9164

92-
return true
65+
return validatePrices(prices, minPrices)
9366
}
9467

9568
// GetInactiveAt returns the inactive time by adding ActiveDuration to the current block time.
@@ -98,3 +71,35 @@ func (k *Keeper) GetInactiveAt(ctx sdk.Context) time.Time {
9871

9972
return ctx.BlockTime().Add(d)
10073
}
74+
75+
// validatePrices checks that all provided prices use allowed denoms and
76+
// meet or exceed the given minimums (zero values and empty lists are valid).
77+
func validatePrices(prices v1base.Prices, minPrices v1base.Prices) error {
78+
// Empty set of prices is valid: treated as zero prices for all denoms.
79+
if prices.Len() == 0 {
80+
return nil
81+
}
82+
83+
// Build a lookup map for minPrices
84+
m := minPrices.Map()
85+
86+
for _, price := range prices {
87+
minPrice, ok := m[price.Denom]
88+
if !ok {
89+
return fmt.Errorf("denom %s is not allowed", price.Denom)
90+
}
91+
92+
// Only check non-zero values
93+
if !price.BaseValue.IsZero() && price.BaseValue.LT(minPrice.BaseValue) {
94+
return fmt.Errorf("base value %s for denom %s is lesser than %s",
95+
price.BaseValue, price.Denom, minPrice.BaseValue)
96+
}
97+
98+
if !price.QuoteValue.IsZero() && price.QuoteValue.LT(minPrice.QuoteValue) {
99+
return fmt.Errorf("quote value %s for denom %s is lesser than %s",
100+
price.QuoteValue, price.Denom, minPrice.QuoteValue)
101+
}
102+
}
103+
104+
return nil
105+
}

x/node/types/errors.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ func NewErrorInvalidPrice(price v1base.Price) error {
6969
}
7070

7171
// NewErrorInvalidPrices returns an error indicating that the provided prices are invalid.
72-
func NewErrorInvalidPrices(prices v1base.Prices) error {
73-
return sdkerrors.Wrapf(ErrInvalidPrices, "invalid prices %s", prices)
72+
func NewErrorInvalidPrices(err error) error {
73+
return sdkerrors.Wrap(ErrInvalidPrices, err.Error())
7474
}
7575

7676
// NewErrorInvalidSessionStatus returns an error indicating that the provided status is invalid for the session.

0 commit comments

Comments
 (0)