@@ -15,9 +15,6 @@ import (
1515 "github.com/gitopia/gitopia/v6/x/storage/types"
1616)
1717
18- // Approximate upgrade time of the v6 upgrade which adds storage module
19- var UpgradeTime = time .Date (2025 , time .September , 5 , 14 , 0 , 0 , 0 , time .UTC )
20-
2118type msgServer struct {
2219 Keeper
2320}
@@ -108,14 +105,15 @@ func (k msgServer) UpdateProvider(goCtx context.Context, msg *types.MsgUpdatePro
108105}
109106
110107// calculateStorageCharge calculates the charge for storage usage beyond free limit
111- func (k msgServer ) calculateStorageCharge (ctx sdk.Context , currentUsage uint64 , newUsage uint64 ) (sdk.Coin , error ) {
108+ func (k msgServer ) calculateStorageCharge (ctx sdk.Context , currentUsage uint64 , diff int64 ) (sdk.Coin , error ) {
112109 params := k .GetParams (ctx )
113110 freeStorageBytes := params .FreeStorageMb * 1024 * 1024 // Convert MB to bytes
114111
115112 // If current usage is already above free limit, charge for the entire diff
116113 if currentUsage > freeStorageBytes {
117- diff := newUsage - currentUsage
114+ // Handle negative diff correctly by checking before subtraction
118115 if diff <= 0 {
116+ // Storage decreased or stayed same, no charge
119117 return sdk .NewCoin (params .StoragePricePerGb .Denom , sdk .ZeroInt ()), nil
120118 }
121119 // Calculate charge in GB and multiply by price per GB
@@ -125,12 +123,13 @@ func (k msgServer) calculateStorageCharge(ctx sdk.Context, currentUsage uint64,
125123 }
126124
127125 // If new usage is below free limit, no charge
128- if newUsage <= freeStorageBytes {
126+ newUsage := int64 (currentUsage ) + diff
127+ if newUsage <= int64 (freeStorageBytes ) {
129128 return sdk .NewCoin (params .StoragePricePerGb .Denom , sdk .ZeroInt ()), nil
130129 }
131130
132131 // Calculate charge for the portion that exceeds free limit
133- excessBytes := newUsage - freeStorageBytes
132+ excessBytes := newUsage - int64 ( freeStorageBytes )
134133 excessGb := float64 (excessBytes ) / (1024 * 1024 * 1024 )
135134 chargeAmount := sdk .NewDec (int64 (excessGb )).Mul (sdk .NewDecFromInt (params .StoragePricePerGb .Amount ))
136135 return sdk .NewCoin (params .StoragePricePerGb .Denom , chargeAmount .TruncateInt ()), nil
@@ -181,8 +180,8 @@ func (k msgServer) UpdateRepositoryPackfile(goCtx context.Context, msg *types.Ms
181180 }
182181
183182 // Calculate storage charge
184- if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () && repository . UpdatedAt > UpgradeTime . Unix () {
185- charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , userQuota . StorageUsed + uint64 ( diff ) )
183+ if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () {
184+ charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , diff )
186185 if err != nil {
187186 return nil , fmt .Errorf ("failed to calculate storage charge: %v" , err )
188187 }
@@ -217,7 +216,16 @@ func (k msgServer) UpdateRepositoryPackfile(goCtx context.Context, msg *types.Ms
217216 existingPackfile .Size_ = msg .Size_
218217 existingPackfile .UpdatedAt = ctx .BlockTime ()
219218
220- userQuota .StorageUsed += uint64 (int64 (userQuota .StorageUsed ) + diff )
219+ // Update storage usage safely handling negative diffs
220+ if diff >= 0 {
221+ userQuota .StorageUsed += uint64 (diff )
222+ } else {
223+ if uint64 (- diff ) > userQuota .StorageUsed {
224+ userQuota .StorageUsed = 0
225+ } else {
226+ userQuota .StorageUsed -= uint64 (- diff )
227+ }
228+ }
221229 k .gitopiaKeeper .SetUserQuota (ctx , userQuota )
222230
223231 k .SetPackfile (ctx , existingPackfile )
@@ -226,12 +234,21 @@ func (k msgServer) UpdateRepositoryPackfile(goCtx context.Context, msg *types.Ms
226234 k .IncreaseCidReferenceCount (ctx , msg .Cid )
227235
228236 storageStats := k .GetStorageStats (ctx )
229- storageStats .TotalPackfileSize += uint64 (diff )
237+ // Update storage stats safely handling negative diffs
238+ if diff >= 0 {
239+ storageStats .TotalPackfileSize += uint64 (diff )
240+ } else {
241+ if uint64 (- diff ) > storageStats .TotalPackfileSize {
242+ storageStats .TotalPackfileSize = 0
243+ } else {
244+ storageStats .TotalPackfileSize -= uint64 (- diff )
245+ }
246+ }
230247 k .SetStorageStats (ctx , storageStats )
231248 } else {
232249 // Calculate storage charge for new packfile
233- if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () && repository . UpdatedAt > UpgradeTime . Unix () {
234- charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , userQuota . StorageUsed + msg .Size_ )
250+ if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () {
251+ charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , int64 ( msg .Size_ ) )
235252 if err != nil {
236253 return nil , fmt .Errorf ("failed to calculate storage charge: %v" , err )
237254 }
@@ -349,19 +366,8 @@ func (k msgServer) UpdateReleaseAssets(goCtx context.Context, msg *types.MsgUpda
349366 }
350367
351368 // Calculate storage charge for the total size difference
352- if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () && repository .UpdatedAt > UpgradeTime .Unix () {
353- var newStorageUsed uint64
354- if totalSizeDiff >= 0 {
355- newStorageUsed = userQuota .StorageUsed + uint64 (totalSizeDiff )
356- } else {
357- if uint64 (- totalSizeDiff ) > userQuota .StorageUsed {
358- newStorageUsed = 0
359- } else {
360- newStorageUsed = userQuota .StorageUsed - uint64 (- totalSizeDiff )
361- }
362- }
363-
364- charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , newStorageUsed )
369+ if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () {
370+ charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , int64 (totalSizeDiff ))
365371 if err != nil {
366372 return nil , fmt .Errorf ("failed to calculate storage charge: %v" , err )
367373 }
@@ -790,8 +796,8 @@ func (k msgServer) UpdateLFSObject(goCtx context.Context, msg *types.MsgUpdateLF
790796 }
791797
792798 // Calculate storage charge for new LFS object
793- if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () && repo . UpdatedAt > UpgradeTime . Unix () {
794- charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , userQuota . StorageUsed + msg .Size_ )
799+ if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () {
800+ charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , int64 ( msg .Size_ ) )
795801 if err != nil {
796802 return nil , fmt .Errorf ("failed to calculate storage charge: %v" , err )
797803 }
@@ -1031,7 +1037,7 @@ func (k msgServer) ApproveRepositoryPackfileUpdate(goCtx context.Context, msg *t
10311037
10321038 // Calculate storage charge
10331039 if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () {
1034- charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , userQuota . StorageUsed + uint64 (diff ))
1040+ charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , int64 (diff ))
10351041 if err != nil {
10361042 k .RemoveProposedPackfileUpdate (ctx , proposal .Id )
10371043 return nil , fmt .Errorf ("failed to calculate storage charge: %v" , err )
@@ -1075,7 +1081,16 @@ func (k msgServer) ApproveRepositoryPackfileUpdate(goCtx context.Context, msg *t
10751081 existingPackfile .Size_ = proposal .Size_
10761082 existingPackfile .UpdatedAt = ctx .BlockTime ()
10771083
1078- userQuota .StorageUsed += uint64 (int64 (userQuota .StorageUsed ) + diff )
1084+ // Update storage usage safely handling negative diffs
1085+ if diff >= 0 {
1086+ userQuota .StorageUsed += uint64 (diff )
1087+ } else {
1088+ if uint64 (- diff ) > userQuota .StorageUsed {
1089+ userQuota .StorageUsed = 0
1090+ } else {
1091+ userQuota .StorageUsed -= uint64 (- diff )
1092+ }
1093+ }
10791094 k .gitopiaKeeper .SetUserQuota (ctx , userQuota )
10801095
10811096 k .SetPackfile (ctx , existingPackfile )
@@ -1084,12 +1099,21 @@ func (k msgServer) ApproveRepositoryPackfileUpdate(goCtx context.Context, msg *t
10841099 k .IncreaseCidReferenceCount (ctx , proposal .Cid )
10851100
10861101 storageStats := k .GetStorageStats (ctx )
1087- storageStats .TotalPackfileSize += uint64 (diff )
1102+ // Update storage stats safely handling negative diffs
1103+ if diff >= 0 {
1104+ storageStats .TotalPackfileSize += uint64 (diff )
1105+ } else {
1106+ if uint64 (- diff ) > storageStats .TotalPackfileSize {
1107+ storageStats .TotalPackfileSize = 0
1108+ } else {
1109+ storageStats .TotalPackfileSize -= uint64 (- diff )
1110+ }
1111+ }
10881112 k .SetStorageStats (ctx , storageStats )
10891113 } else {
10901114 // Calculate storage charge for new packfile
10911115 if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () {
1092- charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , userQuota . StorageUsed + proposal .Size_ )
1116+ charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , int64 ( proposal .Size_ ) )
10931117 if err != nil {
10941118 k .RemoveProposedPackfileUpdate (ctx , proposal .Id )
10951119 return nil , fmt .Errorf ("failed to calculate storage charge: %v" , err )
@@ -1526,18 +1550,7 @@ func (k msgServer) ApproveReleaseAssetsUpdate(goCtx context.Context, msg *types.
15261550
15271551 // Calculate storage charge for the total size difference
15281552 if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () {
1529- var newStorageUsed uint64
1530- if totalSizeDiff >= 0 {
1531- newStorageUsed = userQuota .StorageUsed + uint64 (totalSizeDiff )
1532- } else {
1533- if uint64 (- totalSizeDiff ) > userQuota .StorageUsed {
1534- newStorageUsed = 0
1535- } else {
1536- newStorageUsed = userQuota .StorageUsed - uint64 (- totalSizeDiff )
1537- }
1538- }
1539-
1540- charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , newStorageUsed )
1553+ charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , int64 (totalSizeDiff ))
15411554 if err != nil {
15421555 k .RemoveProposedReleaseAssetsUpdate (ctx , proposal .Id )
15431556 return nil , fmt .Errorf ("failed to calculate storage charge: %v" , err )
@@ -1844,7 +1857,7 @@ func (k msgServer) ApproveLFSObjectUpdate(goCtx context.Context, msg *types.MsgA
18441857
18451858 // Calculate storage charge for new LFS object
18461859 if ! k .GetParams (ctx ).StoragePricePerGb .IsZero () {
1847- charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , userQuota . StorageUsed + proposal .Size_ )
1860+ charge , err := k .calculateStorageCharge (ctx , userQuota .StorageUsed , int64 ( proposal .Size_ ) )
18481861 if err != nil {
18491862 return nil , fmt .Errorf ("failed to calculate storage charge: %v" , err )
18501863 }
0 commit comments