Skip to content

Commit

Permalink
feat: add lease renewal price policy
Browse files Browse the repository at this point in the history
  • Loading branch information
ironman0x7b2 committed Dec 11, 2024
1 parent 6f13d58 commit 1dc8d09
Show file tree
Hide file tree
Showing 18 changed files with 787 additions and 309 deletions.
9 changes: 6 additions & 3 deletions proto/sentinel/lease/v1/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ message EventCreate {
string node_address = 2;
string prov_address = 3;
int64 max_hours = 4;
string price = 5;
string base_price = 5;
string quote_price = 6;
string renewal_price_policy = 7;
}

message EventEnd {
Expand Down Expand Up @@ -40,14 +42,15 @@ message EventRenew {
string node_address = 2;
string prov_address = 3;
int64 max_hours = 4;
string price = 5;
string base_price = 5;
string quote_price = 6;
}

message EventUpdate {
uint64 id = 1 [(gogoproto.customname) = "ID"];
string node_address = 2;
string prov_address = 3;
int64 hours = 4;
bool renewable = 5;
string renewal_price_policy = 5;
string payout_at = 6;
}
14 changes: 8 additions & 6 deletions proto/sentinel/lease/v1/lease.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package sentinel.lease.v1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "sentinel/types/v1/renewal.proto";

option go_package = "github.com/sentinel-official/hub/v12/x/lease/types/v1";
option (gogoproto.equal_all) = false;
Expand All @@ -13,15 +14,16 @@ message Lease {
uint64 id = 1 [(gogoproto.customname) = "ID"];
string prov_address = 2;
string node_address = 3;
cosmos.base.v1beta1.Coin price = 4 [(gogoproto.nullable) = false];
int64 hours = 5;
int64 max_hours = 6;
bool renewable = 7;
google.protobuf.Timestamp inactive_at = 8 [
cosmos.base.v1beta1.DecCoin base_price = 4 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin quote_price = 5 [(gogoproto.nullable) = false];
int64 hours = 6;
int64 max_hours = 7;
sentinel.types.v1.RenewalPricePolicy renewal_price_policy = 8;
google.protobuf.Timestamp inactive_at = 9 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
google.protobuf.Timestamp payout_at = 9 [
google.protobuf.Timestamp payout_at = 10 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
Expand Down
5 changes: 3 additions & 2 deletions proto/sentinel/lease/v1/msg.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sentinel.lease.v1;

import "gogoproto/gogo.proto";
import "sentinel/lease/v1/params.proto";
import "sentinel/types/v1/renewal.proto";

option go_package = "github.com/sentinel-official/hub/v12/x/lease/types/v1";
option (gogoproto.equal_all) = false;
Expand All @@ -25,13 +26,13 @@ message MsgStartLeaseRequest {
string node_address = 2;
int64 hours = 3;
string denom = 4;
bool renewable = 5;
sentinel.types.v1.RenewalPricePolicy renewal_price_policy = 5;
}

message MsgUpdateLeaseRequest {
string from = 1;
uint64 id = 2 [(gogoproto.customname) = "ID"];
bool renewable = 3;
sentinel.types.v1.RenewalPricePolicy renewal_price_policy = 3;
}

message MsgUpdateParamsRequest {
Expand Down
21 changes: 21 additions & 0 deletions proto/sentinel/types/v1/renewal.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
syntax = "proto3";
package sentinel.types.v1;

import "gogoproto/gogo.proto";

option go_package = "github.com/sentinel-official/hub/v12/types/v1";
option (gogoproto.goproto_enum_prefix_all) = false;
option (gogoproto.goproto_enum_stringer_all) = false;
option (gogoproto.goproto_getters_all) = false;

// Enum for renewal price policies
enum RenewalPricePolicy {
RENEWAL_PRICE_POLICY_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "RenewalPricePolicyUnspecified"]; // Default value, do not renew
RENEWAL_PRICE_POLICY_IF_LESSER = 1 [(gogoproto.enumvalue_customname) = "RenewalPricePolicyIfLesser"]; // Renew if the current price is lesser than the previous price
RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL = 2 [(gogoproto.enumvalue_customname) = "RenewalPricePolicyIfLesserOrEqual"]; // Renew if the current price is lesser than or equal to the previous price
RENEWAL_PRICE_POLICY_IF_EQUAL = 3 [(gogoproto.enumvalue_customname) = "RenewalPricePolicyIfEqual"]; // Renew if the current price is equal to the previous price
RENEWAL_PRICE_POLICY_IF_NOT_EQUAL = 4 [(gogoproto.enumvalue_customname) = "RenewalPricePolicyIfNotEqual"]; // Renew if the current price is not equal to the previous price
RENEWAL_PRICE_POLICY_IF_GREATER = 5 [(gogoproto.enumvalue_customname) = "RenewalPricePolicyIfGreater"]; // Renew if the current price is greater than the previous price
RENEWAL_PRICE_POLICY_IF_GREATER_OR_EQUAL = 6 [(gogoproto.enumvalue_customname) = "RenewalPricePolicyIfGreaterOrEqual"]; // Renew if the current price is greater than or equal to the previous price
RENEWAL_PRICE_POLICY_ALWAYS = 7 [(gogoproto.enumvalue_customname) = "RenewalPricePolicyAlways"]; // Always renew
}
121 changes: 121 additions & 0 deletions types/v1/renewal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package v1

import (
"errors"
"fmt"
"strings"

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

// String converts a RenewalPricePolicy to its string representation.
func (r RenewalPricePolicy) String() string {
switch r {
case RenewalPricePolicyIfLesser:
return "if_lesser"
case RenewalPricePolicyIfLesserOrEqual:
return "if_lesser_or_equal"
case RenewalPricePolicyIfEqual:
return "if_equal"
case RenewalPricePolicyIfNotEqual:
return "if_not_equal"
case RenewalPricePolicyIfGreater:
return "if_greater"
case RenewalPricePolicyIfGreaterOrEqual:
return "if_greater_or_equal"
case RenewalPricePolicyAlways:
return "always"
default:
return "unspecified"
}
}

// Equal checks if two RenewalPricePolicy values are equal.
func (r RenewalPricePolicy) Equal(v RenewalPricePolicy) bool {
return r == v
}

// IsValid checks whether the RenewalPricePolicy is a valid value.
func (r RenewalPricePolicy) IsValid() bool {
switch r {
case RenewalPricePolicyUnspecified,
RenewalPricePolicyIfLesser,
RenewalPricePolicyIfLesserOrEqual,
RenewalPricePolicyIfEqual,
RenewalPricePolicyIfNotEqual,
RenewalPricePolicyIfGreater,
RenewalPricePolicyIfGreaterOrEqual,
RenewalPricePolicyAlways:
return true
default:
return false
}
}

// RenewalPricePolicyFromString converts a string to a RenewalPricePolicy.
func RenewalPricePolicyFromString(s string) RenewalPricePolicy {
s = strings.ToLower(s)
switch s {
case "if_lesser":
return RenewalPricePolicyIfLesser
case "if_lesser_or_equal":
return RenewalPricePolicyIfLesserOrEqual
case "if_equal":
return RenewalPricePolicyIfEqual
case "if_not_equal":
return RenewalPricePolicyIfNotEqual
case "if_greater":
return RenewalPricePolicyIfGreater
case "if_greater_or_equal":
return RenewalPricePolicyIfGreaterOrEqual
case "always":
return RenewalPricePolicyAlways
default:
return RenewalPricePolicyUnspecified
}
}

// Validate validates whether a subscription can be renewed based on the policy and given DecCoin conditions.
// Returns an error if the renewal is not allowed or invalid.
func (r RenewalPricePolicy) Validate(currentPrice, previousPrice sdk.DecCoin) error {
// Skip denomination check for RenewalPricePolicyAlways
if r != RenewalPricePolicyAlways && currentPrice.Denom != previousPrice.Denom {
return fmt.Errorf("current price denom %s does not match previous price denom %s", currentPrice.Denom, previousPrice.Denom)
}

// Compare prices based on the policy
switch r {
case RenewalPricePolicyUnspecified:
return fmt.Errorf("renewal policy unspecified")
case RenewalPricePolicyIfLesser:
if !currentPrice.Amount.LT(previousPrice.Amount) {
return fmt.Errorf("current price %s is not less than previous price %s", currentPrice, previousPrice)
}
case RenewalPricePolicyIfLesserOrEqual:
if !currentPrice.Amount.LTE(previousPrice.Amount) {
return fmt.Errorf("current price %s is not less than or equal to previous price %s", currentPrice, previousPrice)
}
case RenewalPricePolicyIfEqual:
if !currentPrice.Amount.Equal(previousPrice.Amount) {
return fmt.Errorf("current price %s is not equal to previous price %s", currentPrice, previousPrice)
}
case RenewalPricePolicyIfNotEqual:
if currentPrice.Amount.Equal(previousPrice.Amount) {
return fmt.Errorf("current price %s is equal to previous price %s", currentPrice, previousPrice)
}
case RenewalPricePolicyIfGreater:
if !currentPrice.Amount.GT(previousPrice.Amount) {
return fmt.Errorf("current price %s is not greater than previous price %s", currentPrice, previousPrice)
}
case RenewalPricePolicyIfGreaterOrEqual:
if !currentPrice.Amount.GTE(previousPrice.Amount) {
return fmt.Errorf("current price %s is not greater than or equal to previous price %s", currentPrice, previousPrice)
}
case RenewalPricePolicyAlways:
return nil
default:
return errors.New("invalid renewal policy")
}

return nil
}
99 changes: 99 additions & 0 deletions types/v1/renewal.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions types/v1/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ func (s Status) String() string {
}

func (s Status) IsValid() bool {
return s == StatusActive ||
s == StatusInactivePending ||
s == StatusInactive
switch s {
case StatusActive,
StatusInactivePending,
StatusInactive:
return true
default:
return false
}
}

func (s Status) Equal(v Status) bool {
Expand Down
22 changes: 20 additions & 2 deletions x/lease/client/cli/flags.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
package cli

import (
"github.com/spf13/pflag"

v1base "github.com/sentinel-official/hub/v12/types/v1"
)

const (
flagDenom = "denom"
flagRenewable = "renewable"
flagDenom = "denom"
flagRenewalPricePolicy = "renewal-price-policy"
)

func GetRenewalPricePolicy(flags *pflag.FlagSet) (v1base.RenewalPricePolicy, error) {
s, err := flags.GetString(flagRenewalPricePolicy)
if err != nil {
return v1base.RenewalPricePolicyUnspecified, err
}
if s == "" {
return v1base.RenewalPricePolicyUnspecified, nil
}

return v1base.RenewalPricePolicyFromString(s), nil
}
Loading

0 comments on commit 1dc8d09

Please sign in to comment.