Skip to content

Commit

Permalink
feat: limit the interval for updating quota (#288)
Browse files Browse the repository at this point in the history
  • Loading branch information
forcodedancing authored Jun 26, 2023
1 parent 0899864 commit 9c1e3bd
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 45 deletions.
2 changes: 2 additions & 0 deletions proto/greenfield/storage/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ message Params {
uint64 discontinue_deletion_max = 14;
// The max number for deleting policy in each end block
uint64 stale_policy_cleanup_max = 15;
// The min interval for making quota smaller in seconds
uint64 min_quota_update_interval = 16;
}

// VersionedParams defines the parameters for the storage module with multi version, each version store with different timestamp.
Expand Down
39 changes: 37 additions & 2 deletions x/storage/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ func (k Keeper) DeleteBucket(ctx sdk.Context, operator sdk.AccAddress, bucketNam

func (k Keeper) doDeleteBucket(ctx sdk.Context, operator sdk.AccAddress, bucketInfo *types.BucketInfo) error {
store := ctx.KVStore(k.storeKey)
bucketKey := types.GetBucketKey(bucketInfo.BucketName)
store.Delete(bucketKey)
store.Delete(types.GetBucketKey(bucketInfo.BucketName))
store.Delete(types.GetBucketByIDKey(bucketInfo.Id))
store.Delete(types.GetQuotaKey(bucketInfo.Id))

if err := k.appendResourceIdForGarbageCollection(ctx, resource.RESOURCE_TYPE_BUCKET, bucketInfo.Id); err != nil {
return err
Expand Down Expand Up @@ -284,6 +284,21 @@ func (k Keeper) UpdateBucketInfo(ctx sdk.Context, operator sdk.AccAddress, bucke
// handle fields not changed
if opts.ChargedReadQuota == nil {
opts.ChargedReadQuota = &bucketInfo.ChargedReadQuota
} else if *opts.ChargedReadQuota != bucketInfo.ChargedReadQuota {
blockTime := uint64(ctx.BlockTime().Unix())
if *opts.ChargedReadQuota < bucketInfo.ChargedReadQuota {
minInterval := k.GetParams(ctx).MinQuotaUpdateInterval
lastUpdateTime, found := k.getQuotaUpdateTime(ctx, bucketInfo.Id)
if !found {
return types.ErrUpdateQuotaFailed
}
if lastUpdateTime+minInterval > blockTime {
return types.ErrUpdateQuotaFailed.Wrapf("The quota can be updated to a smaller value before %d timestamp",
lastUpdateTime+minInterval)
}
}
// save quota update time
k.setQuotaUpdateTime(ctx, bucketInfo.Id, blockTime)
}

if opts.Visibility != types.VISIBILITY_TYPE_UNSPECIFIED {
Expand Down Expand Up @@ -1653,3 +1668,23 @@ func (k Keeper) garbageCollectionForResource(ctx sdk.Context, deleteStalePolicie
}
return deletedTotal, true
}

func (k Keeper) setQuotaUpdateTime(ctx sdk.Context, bucketId types.Uint, timestamp uint64) {
store := ctx.KVStore(k.storeKey)
bz := make([]byte, 8)
binary.BigEndian.PutUint64(bz, timestamp)
store.Set(types.GetQuotaKey(bucketId), bz)
}

func (k Keeper) getQuotaUpdateTime(ctx sdk.Context, bucketId types.Uint) (uint64, bool) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.GetQuotaKey(bucketId))
if bz != nil {
return binary.BigEndian.Uint64(bz), true
}
bucketInfo, found := k.GetBucketInfoById(ctx, bucketId)
if !found {
return 0, false
}
return uint64(bucketInfo.CreateAt), true
}
1 change: 1 addition & 0 deletions x/storage/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var (
ErrInvalidApproval = errors.Register(ModuleName, 1116, "Invalid approval of sp")
ErrChargeFailed = errors.Register(ModuleName, 1117, "charge failed error")
ErrInvalidVisibility = errors.Register(ModuleName, 1118, "Invalid type of visibility")
ErrUpdateQuotaFailed = errors.Register(ModuleName, 1119, "Update quota failed")

ErrNoSuchPolicy = errors.Register(ModuleName, 1120, "No such Policy")
ErrInvalidParameter = errors.Register(ModuleName, 1121, "Invalid parameter")
Expand Down
6 changes: 6 additions & 0 deletions x/storage/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var (
BucketPrefix = []byte{0x11}
ObjectPrefix = []byte{0x12}
GroupPrefix = []byte{0x13}
QuotaPrefix = []byte{0x14}

BucketByIDPrefix = []byte{0x21}
ObjectByIDPrefix = []byte{0x22}
Expand Down Expand Up @@ -133,3 +134,8 @@ func GetDeleteStalePoliciesKey(height int64) []byte {
binary.BigEndian.PutUint64(bz, uint64(height))
return append(DeleteStalePoliciesPrefix, bz...)
}

// GetQuotaKey return the quota store key
func GetQuotaKey(bucketId math.Uint) []byte {
return append(QuotaPrefix, sequence.EncodeSequence(bucketId)...)
}
15 changes: 15 additions & 0 deletions x/storage/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const (
DefaultDiscontinueConfirmPeriod int64 = 604800 // 7 days (in second)
DefaultDiscontinueDeletionMax uint64 = 100
DefaultStalePolicyCleanupMax uint64 = 200
DefaultMinUpdateQuotaInterval uint64 = 2592000 // 30 days (in second)

DefaultMirrorBucketRelayerFee = "250000000000000" // 0.00025
DefaultMirrorBucketAckRelayerFee = "250000000000000" // 0.00025
Expand All @@ -45,6 +46,7 @@ var (
KeyDiscontinueConfirmPeriod = []byte("DiscontinueConfirmPeriod")
KeyDiscontinueDeletionMax = []byte("DiscontinueDeletionMax")
KeyStalePolicyCleanupMax = []byte("StalePolicyCleanupMax")
KeyMinUpdateQuotaInterval = []byte("MinUpdateQuotaInterval")
KeyMirrorBucketRelayerFee = []byte("MirrorBucketRelayerFee")
KeyMirrorBucketAckRelayerFee = []byte("MirrorBucketAckRelayerFee")
KeyMirrorObjectRelayerFee = []byte("MirrorObjectRelayerFee")
Expand All @@ -71,6 +73,7 @@ func NewParams(
discontinueConfirmPeriod int64,
discontinueDeletionMax uint64,
stalePoliesCleanupMax uint64,
minUpdateQuotaInterval uint64,
) Params {
return Params{
VersionedParams: VersionedParams{
Expand All @@ -93,6 +96,7 @@ func NewParams(
DiscontinueConfirmPeriod: discontinueConfirmPeriod,
DiscontinueDeletionMax: discontinueDeletionMax,
StalePolicyCleanupMax: stalePoliesCleanupMax,
MinQuotaUpdateInterval: minUpdateQuotaInterval,
}
}

Expand All @@ -106,6 +110,7 @@ func DefaultParams() Params {
DefaultMirrorGroupRelayerFee, DefaultMirrorGroupAckRelayerFee,
DefaultDiscontinueCountingWindow, DefaultDiscontinueObjectMax, DefaultDiscontinueBucketMax,
DefaultDiscontinueConfirmPeriod, DefaultDiscontinueDeletionMax, DefaultStalePolicyCleanupMax,
DefaultMinUpdateQuotaInterval,
)
}

Expand All @@ -131,6 +136,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
paramtypes.NewParamSetPair(KeyDiscontinueConfirmPeriod, &p.DiscontinueConfirmPeriod, validateDiscontinueConfirmPeriod),
paramtypes.NewParamSetPair(KeyDiscontinueDeletionMax, &p.DiscontinueDeletionMax, validateDiscontinueDeletionMax),
paramtypes.NewParamSetPair(KeyStalePolicyCleanupMax, &p.StalePolicyCleanupMax, validateStalePolicyCleanupMax),
paramtypes.NewParamSetPair(KeyMinUpdateQuotaInterval, &p.MinQuotaUpdateInterval, validateMinUpdateQuotaInterval),
}
}

Expand Down Expand Up @@ -391,3 +397,12 @@ func validateStalePolicyCleanupMax(i interface{}) error {
}
return nil
}

func validateMinUpdateQuotaInterval(i interface{}) error {
_, ok := i.(uint64)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}

return nil
}
125 changes: 82 additions & 43 deletions x/storage/types/params.pb.go

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

0 comments on commit 9c1e3bd

Please sign in to comment.