Skip to content

Commit

Permalink
fix: fix deleting issue for paymaster (#624)
Browse files Browse the repository at this point in the history
* fix: fix deleting issue for paymaster

* fix lint issue

* check limit status when migrate bucket

* prevent migrate bucket when bucket is rate limited
  • Loading branch information
yutianwu authored May 23, 2024
1 parent bd6a0f4 commit 88e71c5
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 1 deletion.
1 change: 1 addition & 0 deletions deployment/localup/localup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ function generate_genesis() {
echo -e '[[upgrade]]\nname = "Pawnee"\nheight = 23\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml
echo -e '[[upgrade]]\nname = "Serengeti"\nheight = 24\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml
echo -e '[[upgrade]]\nname = "Erdos"\nheight = 25\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml
echo -e '[payment-check]\nenabled = true\ninterval = 1' >> ${workspace}/.local/validator${i}/config/app.toml
done

# enable swagger API for validator0
Expand Down
2 changes: 1 addition & 1 deletion e2e/core/basesuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (s *BaseSuite) SetupSuite() {
// Create a GVG for each sp by default
deposit := sdk.Coin{
Denom: s.Config.Denom,
Amount: types.NewIntFromInt64WithDecimal(1, types.DecimalBNB),
Amount: types.NewIntFromInt64WithDecimal(1000, types.DecimalBNB),
}
var secondaryIDs []uint32
for _, ssp := range s.StorageProviders {
Expand Down
97 changes: 97 additions & 0 deletions e2e/tests/storage_rate_limit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,103 @@ func (s *StorageTestSuite) TestSetBucketRateLimitToZero() {
s.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit")
}

func (s *StorageTestSuite) TestSetBucketRateLimitToZeroAndDelete() {
var err error
sp := s.BaseSuite.PickStorageProvider()
gvg, found := sp.GetFirstGlobalVirtualGroup()
s.Require().True(found)
user := s.User
// CreateBucket
bucketName := storageutils.GenRandomBucketName()
msgCreateBucket := storagetypes.NewMsgCreateBucket(
user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(),
nil, math.MaxUint, nil, 0)
msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId
msgCreateBucket.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes())
s.Require().NoError(err)
s.SendTxBlock(user, msgCreateBucket)

// HeadBucket
ctx := context.Background()
queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{
BucketName: bucketName,
}
queryHeadBucketResponse, err := s.Client.HeadBucket(ctx, &queryHeadBucketRequest)
s.Require().NoError(err)
s.Require().Equal(queryHeadBucketResponse.BucketInfo.BucketName, bucketName)
s.Require().Equal(queryHeadBucketResponse.BucketInfo.Owner, user.GetAddr().String())
s.Require().Equal(queryHeadBucketResponse.BucketInfo.GlobalVirtualGroupFamilyId, gvg.FamilyId)
s.Require().Equal(queryHeadBucketResponse.BucketInfo.PaymentAddress, user.GetAddr().String())
s.Require().Equal(queryHeadBucketResponse.BucketInfo.Visibility, storagetypes.VISIBILITY_TYPE_PUBLIC_READ)
s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN)

queryQuotaUpdateTimeResponse, err := s.Client.QueryQuotaUpdateTime(ctx, &storagetypes.QueryQuoteUpdateTimeRequest{
BucketName: bucketName,
})
s.Require().NoError(err)
s.Require().Equal(queryHeadBucketResponse.BucketInfo.CreateAt, queryQuotaUpdateTimeResponse.UpdateAt)

fmt.Printf("User: %s\n", s.User.GetAddr().String())
fmt.Printf("queryHeadBucketResponse.BucketInfo.Owner: %s\n", queryHeadBucketResponse.BucketInfo.Owner)
fmt.Printf("queryHeadBucketResponse.BucketInfo.PaymentAccount: %s\n", queryHeadBucketResponse.BucketInfo.PaymentAddress)

// SetBucketRateLimit
msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(s.User.GetAddr(), s.User.GetAddr(), s.User.GetAddr(), bucketName, sdkmath.NewInt(100000000000000000))
s.SendTxBlock(s.User, msgSetBucketRateLimit)

// CreateObject
objectName := storageutils.GenRandomObjectName()
// create test buffer
var buffer bytes.Buffer
// Create 1MiB content where each line contains 1024 characters.
for i := 0; i < 1024; i++ {
buffer.WriteString(fmt.Sprintf("[%05d] %s\n", i, line))
}
payloadSize := buffer.Len()
checksum := sdk.Keccak256(buffer.Bytes())
expectChecksum := [][]byte{checksum, checksum, checksum, checksum, checksum, checksum, checksum}
contextType := "text/event-stream"
msgCreateObject := storagetypes.NewMsgCreateObject(user.GetAddr(), bucketName, objectName, uint64(payloadSize), storagetypes.VISIBILITY_TYPE_PRIVATE, expectChecksum, contextType, storagetypes.REDUNDANCY_EC_TYPE, math.MaxUint, nil)
msgCreateObject.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateObject.GetApprovalBytes())
s.Require().NoError(err)
s.SendTxBlock(s.User, msgCreateObject)

// HeadObject
queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{
BucketName: bucketName,
ObjectName: objectName,
}
queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest)
s.Require().NoError(err)

// SealObject
gvgId := gvg.Id
msgSealObject := storagetypes.NewMsgSealObject(sp.SealKey.GetAddr(), bucketName, objectName, gvg.Id, nil)
secondarySigs := make([][]byte, 0)
secondarySPBlsPubKeys := make([]bls.PublicKey, 0)
blsSignHash := storagetypes.NewSecondarySpSealObjectSignDoc(s.GetChainID(), gvgId, queryHeadObjectResponse.ObjectInfo.Id, storagetypes.GenerateHash(queryHeadObjectResponse.ObjectInfo.Checksums[:])).GetBlsSignHash()
// every secondary sp signs the checksums
for _, spID := range gvg.SecondarySpIds {
sig, err := core.BlsSignAndVerify(s.StorageProviders[spID], blsSignHash)
s.Require().NoError(err)
secondarySigs = append(secondarySigs, sig)
pk, err := bls.PublicKeyFromBytes(s.StorageProviders[spID].BlsKey.PubKey().Bytes())
s.Require().NoError(err)
secondarySPBlsPubKeys = append(secondarySPBlsPubKeys, pk)
}
aggBlsSig, err := core.BlsAggregateAndVerify(secondarySPBlsPubKeys, blsSignHash, secondarySigs)
s.Require().NoError(err)
msgSealObject.SecondarySpBlsAggSignatures = aggBlsSig
s.T().Logf("msg %s", msgSealObject.String())
s.SendTxBlock(sp.SealKey, msgSealObject)

msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(s.User.GetAddr(), s.User.GetAddr(), s.User.GetAddr(), bucketName, sdkmath.NewInt(0))
s.SendTxBlock(s.User, msgSetBucketRateLimit)

msgDeleteObject := storagetypes.NewMsgDeleteObject(user.GetAddr(), bucketName, objectName)
s.SendTxBlockWithExpectErrorString(msgDeleteObject, user, "bucket is rate limited")
}

// TestNotOwnerSetBucketRateLimit_Object
// 1. user create a bucket with 0 read quota
// 2. the payment account set the rate limit
Expand Down
7 changes: 7 additions & 0 deletions x/storage/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,13 @@ func (k Keeper) MigrateBucket(ctx sdk.Context, operator sdk.AccAddress, bucketNa
return err
}

if ctx.IsUpgraded(upgradetypes.Erdos) {
isRateLimited := k.IsBucketRateLimited(ctx, bucketInfo.BucketName)
if isRateLimited {
return fmt.Errorf("bucket is rate limited: %s", bucketInfo.BucketName)
}
}

key := types.GetMigrationBucketKey(bucketInfo.Id)
if store.Has(key) {
panic("migration bucket key is existed.")
Expand Down
9 changes: 9 additions & 0 deletions x/storage/keeper/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,10 @@ func (k Keeper) ChargeViaObjectChange(ctx sdk.Context, bucketInfo *storagetypes.
shouldApplyFlowRate = false
}
} else {
isRateLimited := k.IsBucketRateLimited(ctx, bucketInfo.BucketName)
if isRateLimited {
return nil, fmt.Errorf("bucket is rate limited: %s", bucketInfo.BucketName)
}
// we should only check the flow rate limit when is not forced
currentBill, err := k.GetBucketReadStoreBill(ctx, bucketInfo, internalBucketInfo)
if err != nil {
Expand Down Expand Up @@ -598,6 +602,11 @@ func (k Keeper) ChargeBucketReadStoreFee(ctx sdk.Context, bucketInfo *storagetyp
}

if ctx.IsUpgraded(upgradetypes.Erdos) {
isRateLimited := k.IsBucketRateLimited(ctx, bucketInfo.BucketName)
if isRateLimited {
return fmt.Errorf("bucket is rate limited: %s", bucketInfo.BucketName)
}

err := k.isBucketFlowRateUnderLimit(ctx, sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress), sdk.MustAccAddressFromHex(bucketInfo.Owner), bucketInfo.BucketName, bill)
if err != nil {
return err
Expand Down

0 comments on commit 88e71c5

Please sign in to comment.