From 6a9059821518e7840b53f985fa3d90a77168e988 Mon Sep 17 00:00:00 2001 From: yutianwu Date: Mon, 1 Apr 2024 11:47:44 +0800 Subject: [PATCH 1/8] feat: remove set bucket flow rate limit message --- app/upgrade.go | 1 - 1 file changed, 1 deletion(-) diff --git a/app/upgrade.go b/app/upgrade.go index 7d4e34531..cc1dc0bf2 100644 --- a/app/upgrade.go +++ b/app/upgrade.go @@ -227,7 +227,6 @@ func (app *App) registerSerengetiUpgradeHandler() { app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgDelegateCreateObject{}), 1.2e3)) app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgDelegateUpdateObjectContent{}), 1.2e3)) app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgSealObjectV2{}), 1.2e2)) - app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgSetBucketFlowRateLimit{}), 1.2e3)) return app.mm.RunMigrations(ctx, app.configurator, fromVM) }) From c5d5f42df57c26b2b6898e7c58ac92dae6da0077 Mon Sep 17 00:00:00 2001 From: yutianwu Date: Mon, 1 Apr 2024 12:33:42 +0800 Subject: [PATCH 2/8] comment related test cases --- e2e/tests/storage_rate_limit_test.go | 809 ++++++++++++++------------- 1 file changed, 405 insertions(+), 404 deletions(-) diff --git a/e2e/tests/storage_rate_limit_test.go b/e2e/tests/storage_rate_limit_test.go index e2e01bd8d..4e07aabe5 100644 --- a/e2e/tests/storage_rate_limit_test.go +++ b/e2e/tests/storage_rate_limit_test.go @@ -1,406 +1,407 @@ package tests -import ( - "bytes" - "context" - "fmt" - "math" - - sdkmath "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - - storageutils "github.com/bnb-chain/greenfield/testutil/storage" - storagetypes "github.com/bnb-chain/greenfield/x/storage/types" -) - -func (s *StorageTestSuite) TestSetBucketRateLimitToZero() { - 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, 10000000) - 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(0)) - s.SendTxBlock(s.User, msgSetBucketRateLimit) - - queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ - BucketName: bucketName, - } - queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) - s.Require().NoError(err) - - s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) - s.Require().Equal(queryHeadBucketResponse.ExtraInfo.FlowRateLimit.String(), "0") - - // 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.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit") -} - -// TestNotOwnerSetBucketRateLimit_Object -// 1. user create a bucket with 0 read quota -// 2. the payment account set the rate limit -// 3. user create an object in the bucket -// 4. the payment account set the rate limit to 0 -// 5. user create an object in the bucket and it should fail -// 6. the payment account set the rate limit to a positive number -// 7. user create an object in the bucket and it should pass -func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Object() { - var err error - sp := s.BaseSuite.PickStorageProvider() - gvg, found := sp.GetFirstGlobalVirtualGroup() - s.Require().True(found) - user := s.User - paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] - - // CreateBucket - bucketName := storageutils.GenRandomBucketName() - - msgCreateBucket := storagetypes.NewMsgCreateBucket( - user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), - paymentAcc.GetAddr(), 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, paymentAcc.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) - - // SetBucketRateLimit - msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) - s.SendTxBlock(paymentAcc, 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(user, msgCreateObject) - - // SetBucketRateLimit - msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) - s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) - - // CreateObject - objectName = storageutils.GenRandomObjectName() - 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.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit") - - // SetBucketRateLimit - msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) - s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) - - // create object - objectName = storageutils.GenRandomObjectName() - 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(user, msgCreateObject) -} - -// TestNotOwnerSetBucketRateLimit_Bucket -// 1. user create a bucket with 0 read quota -// 2. the payment account set the rate limit -// 3. user update the read quota to a positive number -// 4. the payment account set the rate limit to 0 -// 5. user update the read quota to a positive number and it should fail -// 6. the payment account set the rate limit to a positive number -// 7. user update the read quota to a positive number and it should pass -func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Bucket() { - var err error - sp := s.BaseSuite.PickStorageProvider() - gvg, found := sp.GetFirstGlobalVirtualGroup() - s.Require().True(found) - user := s.User - paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] - - // CreateBucket - bucketName := storageutils.GenRandomBucketName() - - msgCreateBucket := storagetypes.NewMsgCreateBucket( - user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), - paymentAcc.GetAddr(), 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, paymentAcc.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) - - // SetBucketRateLimit - msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000)) - s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) - - // UpdateBucketInfo - var readQuota uint64 = 100 - msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( - user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) - s.SendTxBlock(user, msgUpdateBucketInfo) - - // SetBucketRateLimit - msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) - s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) - - queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ - BucketName: bucketName, - } - queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) - s.Require().NoError(err) - - s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) - - // update bucket - readQuota = 101 - msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( - user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) - s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "payment account is not changed but the bucket is limited") - - // SetBucketRateLimit - msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000)) - s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) - - queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ - BucketName: bucketName, - } - queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) - s.Require().NoError(err) - - s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, false) - - // update bucket - readQuota = 102 - msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( - user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) - s.SendTxBlock(user, msgUpdateBucketInfo) -} - -// TestNotOwnerSetBucketRateLimit_BucketPaymentAccount -// 1. user create a bucket with positive read quota -// 2. user set the rate limit to 0 -// 3. update the payment account to another payment account, it should fail -// 4. the payment account set the rate limit to 0 -// 5. user update the payment account to another payment account, it should fail -// 6. the payment account set the rate limit to a positive number -// 7. user update the payment account to another payment account, it should pass -func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_BucketPaymentAccount() { - var err error - sp := s.BaseSuite.PickStorageProvider() - gvg, found := sp.GetFirstGlobalVirtualGroup() - s.Require().True(found) - user := s.User - paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] - - // CreateBucket - bucketName := storageutils.GenRandomBucketName() - - msgCreateBucket := storagetypes.NewMsgCreateBucket( - user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), - user.GetAddr(), math.MaxUint, nil, 100) - 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, s.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) - - // SetBucketRateLimit - msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(s.User.GetAddr(), s.User.GetAddr(), s.User.GetAddr(), bucketName, sdkmath.NewInt(0)) - s.SendTxBlock(s.User, msgSetBucketRateLimit) - - // SetBucketRateLimit - msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( - user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) - s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "the flow rate limit is not set") - - // SetBucketRateLimit - msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) - s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) - - queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ - BucketName: bucketName, - } - queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) - s.Require().NoError(err) - - s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) - - // UpdateBucketInfo - msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( - user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) - s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "greater than the flow rate limit") - - // SetBucketRateLimit - msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) - s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) - - // UpdateBucketInfo - msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( - user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) - s.SendTxBlock(user, msgUpdateBucketInfo) - - queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ - BucketName: bucketName, - } - queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) - s.Require().NoError(err) - - s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, false) -} - -func (s *StorageTestSuite) TestQueryBucketRateLimit() { - var err error - sp := s.BaseSuite.PickStorageProvider() - gvg, found := sp.GetFirstGlobalVirtualGroup() - s.Require().True(found) - user := s.User - paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] - - // CreateBucket - bucketName := storageutils.GenRandomBucketName() - - msgCreateBucket := storagetypes.NewMsgCreateBucket( - user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), - paymentAcc.GetAddr(), 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) - - // SetBucketRateLimit - msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) - s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) - - // update bucket - var readQuota uint64 = 100 - msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( - user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) - s.SendTxBlock(user, msgUpdateBucketInfo) - - s.Require().NoError(err) - - // QueryBucketRateLimit - ctx := context.Background() - queryBucketRateLimitRequest := storagetypes.QueryPaymentAccountBucketFlowRateLimitRequest{ - PaymentAccount: paymentAcc.GetAddr().String(), - BucketName: bucketName, - BucketOwner: user.GetAddr().String(), - } - queryBucketRateLimitResponse, err := s.Client.QueryPaymentAccountBucketFlowRateLimit(ctx, &queryBucketRateLimitRequest) - s.Require().NoError(err) - s.Require().Equal(queryBucketRateLimitResponse.IsSet, true) - s.Require().Equal(queryBucketRateLimitResponse.FlowRateLimit, sdkmath.NewInt(100000000000000)) -} +// +//import ( +// "bytes" +// "context" +// "fmt" +// "math" +// +// sdkmath "cosmossdk.io/math" +// sdk "github.com/cosmos/cosmos-sdk/types" +// +// storageutils "github.com/bnb-chain/greenfield/testutil/storage" +// storagetypes "github.com/bnb-chain/greenfield/x/storage/types" +//) +// +//func (s *StorageTestSuite) TestSetBucketRateLimitToZero() { +// 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, 10000000) +// 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(0)) +// s.SendTxBlock(s.User, msgSetBucketRateLimit) +// +// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ +// BucketName: bucketName, +// } +// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) +// s.Require().NoError(err) +// +// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) +// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.FlowRateLimit.String(), "0") +// +// // 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.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit") +//} +// +//// TestNotOwnerSetBucketRateLimit_Object +//// 1. user create a bucket with 0 read quota +//// 2. the payment account set the rate limit +//// 3. user create an object in the bucket +//// 4. the payment account set the rate limit to 0 +//// 5. user create an object in the bucket and it should fail +//// 6. the payment account set the rate limit to a positive number +//// 7. user create an object in the bucket and it should pass +//func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Object() { +// var err error +// sp := s.BaseSuite.PickStorageProvider() +// gvg, found := sp.GetFirstGlobalVirtualGroup() +// s.Require().True(found) +// user := s.User +// paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] +// +// // CreateBucket +// bucketName := storageutils.GenRandomBucketName() +// +// msgCreateBucket := storagetypes.NewMsgCreateBucket( +// user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), +// paymentAcc.GetAddr(), 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, paymentAcc.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) +// +// // SetBucketRateLimit +// msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) +// s.SendTxBlock(paymentAcc, 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(user, msgCreateObject) +// +// // SetBucketRateLimit +// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) +// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) +// +// // CreateObject +// objectName = storageutils.GenRandomObjectName() +// 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.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit") +// +// // SetBucketRateLimit +// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) +// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) +// +// // create object +// objectName = storageutils.GenRandomObjectName() +// 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(user, msgCreateObject) +//} +// +//// TestNotOwnerSetBucketRateLimit_Bucket +//// 1. user create a bucket with 0 read quota +//// 2. the payment account set the rate limit +//// 3. user update the read quota to a positive number +//// 4. the payment account set the rate limit to 0 +//// 5. user update the read quota to a positive number and it should fail +//// 6. the payment account set the rate limit to a positive number +//// 7. user update the read quota to a positive number and it should pass +//func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Bucket() { +// var err error +// sp := s.BaseSuite.PickStorageProvider() +// gvg, found := sp.GetFirstGlobalVirtualGroup() +// s.Require().True(found) +// user := s.User +// paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] +// +// // CreateBucket +// bucketName := storageutils.GenRandomBucketName() +// +// msgCreateBucket := storagetypes.NewMsgCreateBucket( +// user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), +// paymentAcc.GetAddr(), 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, paymentAcc.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) +// +// // SetBucketRateLimit +// msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000)) +// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) +// +// // UpdateBucketInfo +// var readQuota uint64 = 100 +// msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( +// user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) +// s.SendTxBlock(user, msgUpdateBucketInfo) +// +// // SetBucketRateLimit +// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) +// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) +// +// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ +// BucketName: bucketName, +// } +// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) +// s.Require().NoError(err) +// +// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) +// +// // update bucket +// readQuota = 101 +// msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( +// user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) +// s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "payment account is not changed but the bucket is limited") +// +// // SetBucketRateLimit +// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000)) +// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) +// +// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ +// BucketName: bucketName, +// } +// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) +// s.Require().NoError(err) +// +// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, false) +// +// // update bucket +// readQuota = 102 +// msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( +// user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) +// s.SendTxBlock(user, msgUpdateBucketInfo) +//} +// +//// TestNotOwnerSetBucketRateLimit_BucketPaymentAccount +//// 1. user create a bucket with positive read quota +//// 2. user set the rate limit to 0 +//// 3. update the payment account to another payment account, it should fail +//// 4. the payment account set the rate limit to 0 +//// 5. user update the payment account to another payment account, it should fail +//// 6. the payment account set the rate limit to a positive number +//// 7. user update the payment account to another payment account, it should pass +//func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_BucketPaymentAccount() { +// var err error +// sp := s.BaseSuite.PickStorageProvider() +// gvg, found := sp.GetFirstGlobalVirtualGroup() +// s.Require().True(found) +// user := s.User +// paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] +// +// // CreateBucket +// bucketName := storageutils.GenRandomBucketName() +// +// msgCreateBucket := storagetypes.NewMsgCreateBucket( +// user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), +// user.GetAddr(), math.MaxUint, nil, 100) +// 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, s.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) +// +// // SetBucketRateLimit +// msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(s.User.GetAddr(), s.User.GetAddr(), s.User.GetAddr(), bucketName, sdkmath.NewInt(0)) +// s.SendTxBlock(s.User, msgSetBucketRateLimit) +// +// // SetBucketRateLimit +// msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( +// user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) +// s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "the flow rate limit is not set") +// +// // SetBucketRateLimit +// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) +// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) +// +// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ +// BucketName: bucketName, +// } +// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) +// s.Require().NoError(err) +// +// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) +// +// // UpdateBucketInfo +// msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( +// user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) +// s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "greater than the flow rate limit") +// +// // SetBucketRateLimit +// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) +// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) +// +// // UpdateBucketInfo +// msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( +// user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) +// s.SendTxBlock(user, msgUpdateBucketInfo) +// +// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ +// BucketName: bucketName, +// } +// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) +// s.Require().NoError(err) +// +// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, false) +//} +// +//func (s *StorageTestSuite) TestQueryBucketRateLimit() { +// var err error +// sp := s.BaseSuite.PickStorageProvider() +// gvg, found := sp.GetFirstGlobalVirtualGroup() +// s.Require().True(found) +// user := s.User +// paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] +// +// // CreateBucket +// bucketName := storageutils.GenRandomBucketName() +// +// msgCreateBucket := storagetypes.NewMsgCreateBucket( +// user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), +// paymentAcc.GetAddr(), 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) +// +// // SetBucketRateLimit +// msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) +// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) +// +// // update bucket +// var readQuota uint64 = 100 +// msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( +// user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) +// s.SendTxBlock(user, msgUpdateBucketInfo) +// +// s.Require().NoError(err) +// +// // QueryBucketRateLimit +// ctx := context.Background() +// queryBucketRateLimitRequest := storagetypes.QueryPaymentAccountBucketFlowRateLimitRequest{ +// PaymentAccount: paymentAcc.GetAddr().String(), +// BucketName: bucketName, +// BucketOwner: user.GetAddr().String(), +// } +// queryBucketRateLimitResponse, err := s.Client.QueryPaymentAccountBucketFlowRateLimit(ctx, &queryBucketRateLimitRequest) +// s.Require().NoError(err) +// s.Require().Equal(queryBucketRateLimitResponse.IsSet, true) +// s.Require().Equal(queryBucketRateLimitResponse.FlowRateLimit, sdkmath.NewInt(100000000000000)) +//} From 0084869699eec6caf1e51e82af3c4c4944944cf1 Mon Sep 17 00:00:00 2001 From: yutianwu Date: Mon, 1 Apr 2024 15:48:58 +0800 Subject: [PATCH 3/8] fix: fix uncharge issue when force-deleting objects --- e2e/tests/storage_rate_limit_test.go | 887 +++++++++++++++------------ x/storage/keeper/payment.go | 42 +- 2 files changed, 514 insertions(+), 415 deletions(-) diff --git a/e2e/tests/storage_rate_limit_test.go b/e2e/tests/storage_rate_limit_test.go index 4e07aabe5..9dec8bd46 100644 --- a/e2e/tests/storage_rate_limit_test.go +++ b/e2e/tests/storage_rate_limit_test.go @@ -1,407 +1,484 @@ package tests -// -//import ( -// "bytes" -// "context" -// "fmt" -// "math" -// -// sdkmath "cosmossdk.io/math" -// sdk "github.com/cosmos/cosmos-sdk/types" -// -// storageutils "github.com/bnb-chain/greenfield/testutil/storage" -// storagetypes "github.com/bnb-chain/greenfield/x/storage/types" -//) -// -//func (s *StorageTestSuite) TestSetBucketRateLimitToZero() { -// 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, 10000000) -// 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(0)) -// s.SendTxBlock(s.User, msgSetBucketRateLimit) -// -// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ -// BucketName: bucketName, -// } -// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) -// s.Require().NoError(err) -// -// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) -// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.FlowRateLimit.String(), "0") -// -// // 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.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit") -//} -// -//// TestNotOwnerSetBucketRateLimit_Object -//// 1. user create a bucket with 0 read quota -//// 2. the payment account set the rate limit -//// 3. user create an object in the bucket -//// 4. the payment account set the rate limit to 0 -//// 5. user create an object in the bucket and it should fail -//// 6. the payment account set the rate limit to a positive number -//// 7. user create an object in the bucket and it should pass -//func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Object() { -// var err error -// sp := s.BaseSuite.PickStorageProvider() -// gvg, found := sp.GetFirstGlobalVirtualGroup() -// s.Require().True(found) -// user := s.User -// paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] -// -// // CreateBucket -// bucketName := storageutils.GenRandomBucketName() -// -// msgCreateBucket := storagetypes.NewMsgCreateBucket( -// user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), -// paymentAcc.GetAddr(), 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, paymentAcc.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) -// -// // SetBucketRateLimit -// msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) -// s.SendTxBlock(paymentAcc, 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(user, msgCreateObject) -// -// // SetBucketRateLimit -// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) -// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) -// -// // CreateObject -// objectName = storageutils.GenRandomObjectName() -// 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.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit") -// -// // SetBucketRateLimit -// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) -// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) -// -// // create object -// objectName = storageutils.GenRandomObjectName() -// 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(user, msgCreateObject) -//} -// -//// TestNotOwnerSetBucketRateLimit_Bucket -//// 1. user create a bucket with 0 read quota -//// 2. the payment account set the rate limit -//// 3. user update the read quota to a positive number -//// 4. the payment account set the rate limit to 0 -//// 5. user update the read quota to a positive number and it should fail -//// 6. the payment account set the rate limit to a positive number -//// 7. user update the read quota to a positive number and it should pass -//func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Bucket() { -// var err error -// sp := s.BaseSuite.PickStorageProvider() -// gvg, found := sp.GetFirstGlobalVirtualGroup() -// s.Require().True(found) -// user := s.User -// paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] -// -// // CreateBucket -// bucketName := storageutils.GenRandomBucketName() -// -// msgCreateBucket := storagetypes.NewMsgCreateBucket( -// user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), -// paymentAcc.GetAddr(), 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, paymentAcc.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) -// -// // SetBucketRateLimit -// msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000)) -// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) -// -// // UpdateBucketInfo -// var readQuota uint64 = 100 -// msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( -// user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) -// s.SendTxBlock(user, msgUpdateBucketInfo) -// -// // SetBucketRateLimit -// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) -// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) -// -// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ -// BucketName: bucketName, -// } -// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) -// s.Require().NoError(err) -// -// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) -// -// // update bucket -// readQuota = 101 -// msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( -// user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) -// s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "payment account is not changed but the bucket is limited") -// -// // SetBucketRateLimit -// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000)) -// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) -// -// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ -// BucketName: bucketName, -// } -// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) -// s.Require().NoError(err) -// -// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, false) -// -// // update bucket -// readQuota = 102 -// msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( -// user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) -// s.SendTxBlock(user, msgUpdateBucketInfo) -//} -// -//// TestNotOwnerSetBucketRateLimit_BucketPaymentAccount -//// 1. user create a bucket with positive read quota -//// 2. user set the rate limit to 0 -//// 3. update the payment account to another payment account, it should fail -//// 4. the payment account set the rate limit to 0 -//// 5. user update the payment account to another payment account, it should fail -//// 6. the payment account set the rate limit to a positive number -//// 7. user update the payment account to another payment account, it should pass -//func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_BucketPaymentAccount() { -// var err error -// sp := s.BaseSuite.PickStorageProvider() -// gvg, found := sp.GetFirstGlobalVirtualGroup() -// s.Require().True(found) -// user := s.User -// paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] -// -// // CreateBucket -// bucketName := storageutils.GenRandomBucketName() -// -// msgCreateBucket := storagetypes.NewMsgCreateBucket( -// user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), -// user.GetAddr(), math.MaxUint, nil, 100) -// 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, s.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) -// -// // SetBucketRateLimit -// msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(s.User.GetAddr(), s.User.GetAddr(), s.User.GetAddr(), bucketName, sdkmath.NewInt(0)) -// s.SendTxBlock(s.User, msgSetBucketRateLimit) -// -// // SetBucketRateLimit -// msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( -// user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) -// s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "the flow rate limit is not set") -// -// // SetBucketRateLimit -// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) -// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) -// -// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ -// BucketName: bucketName, -// } -// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) -// s.Require().NoError(err) -// -// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) -// -// // UpdateBucketInfo -// msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( -// user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) -// s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "greater than the flow rate limit") -// -// // SetBucketRateLimit -// msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) -// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) -// -// // UpdateBucketInfo -// msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( -// user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) -// s.SendTxBlock(user, msgUpdateBucketInfo) -// -// queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ -// BucketName: bucketName, -// } -// queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) -// s.Require().NoError(err) -// -// s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, false) -//} -// -//func (s *StorageTestSuite) TestQueryBucketRateLimit() { -// var err error -// sp := s.BaseSuite.PickStorageProvider() -// gvg, found := sp.GetFirstGlobalVirtualGroup() -// s.Require().True(found) -// user := s.User -// paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] -// -// // CreateBucket -// bucketName := storageutils.GenRandomBucketName() -// -// msgCreateBucket := storagetypes.NewMsgCreateBucket( -// user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), -// paymentAcc.GetAddr(), 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) -// -// // SetBucketRateLimit -// msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) -// s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) -// -// // update bucket -// var readQuota uint64 = 100 -// msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( -// user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) -// s.SendTxBlock(user, msgUpdateBucketInfo) -// -// s.Require().NoError(err) -// -// // QueryBucketRateLimit -// ctx := context.Background() -// queryBucketRateLimitRequest := storagetypes.QueryPaymentAccountBucketFlowRateLimitRequest{ -// PaymentAccount: paymentAcc.GetAddr().String(), -// BucketName: bucketName, -// BucketOwner: user.GetAddr().String(), -// } -// queryBucketRateLimitResponse, err := s.Client.QueryPaymentAccountBucketFlowRateLimit(ctx, &queryBucketRateLimitRequest) -// s.Require().NoError(err) -// s.Require().Equal(queryBucketRateLimitResponse.IsSet, true) -// s.Require().Equal(queryBucketRateLimitResponse.FlowRateLimit, sdkmath.NewInt(100000000000000)) -//} +import ( + "bytes" + "context" + "fmt" + "math" + "strconv" + "time" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + gashubtypes "github.com/cosmos/cosmos-sdk/x/gashub/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + + types2 "github.com/bnb-chain/greenfield/sdk/types" + + storageutils "github.com/bnb-chain/greenfield/testutil/storage" + storagetypes "github.com/bnb-chain/greenfield/x/storage/types" +) + +func (s *StorageTestSuite) enableMessage() { + msgSetBucketFlowRateLimit := sdk.MsgTypeURL(&storagetypes.MsgSetBucketFlowRateLimit{}) + msgMigrateBuketGasParams := gashubtypes.NewMsgGasParamsWithFixedGas(msgSetBucketFlowRateLimit, 1.2e3) + + msgUpdateGasParams := gashubtypes.NewMsgSetMsgGasParams(authtypes.NewModuleAddress(govtypes.ModuleName).String(), []*gashubtypes.MsgGasParams{msgMigrateBuketGasParams}, nil) + + var err error + validator := s.Validator.GetAddr() + + ctx := context.Background() + + msgProposal, err := govtypesv1.NewMsgSubmitProposal( + []sdk.Msg{msgUpdateGasParams}, + sdk.Coins{sdk.NewCoin(s.BaseSuite.Config.Denom, types2.NewIntFromInt64WithDecimal(100, types2.DecimalBNB))}, + validator.String(), + "test", "test", "test", + ) + s.Require().NoError(err) + + txRes := s.SendTxBlock(s.Validator, msgProposal) + s.Require().Equal(txRes.Code, uint32(0)) + + // 3. query proposal and get proposal ID + var proposalId uint64 + for _, event := range txRes.Logs[0].Events { + if event.Type == "submit_proposal" { + for _, attr := range event.Attributes { + if attr.Key == "proposal_id" { + proposalId, err = strconv.ParseUint(attr.Value, 10, 0) + s.Require().NoError(err) + break + } + } + break + } + } + s.Require().True(proposalId != 0) + + queryProposal := &govtypesv1.QueryProposalRequest{ProposalId: proposalId} + _, err = s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) + s.Require().NoError(err) + + // 4. submit MsgVote and wait the proposal exec + msgVote := govtypesv1.NewMsgVote(validator, proposalId, govtypesv1.OptionYes, "test") + txRes = s.SendTxBlock(s.Validator, msgVote) + s.Require().Equal(txRes.Code, uint32(0)) + + queryVoteParamsReq := govtypesv1.QueryParamsRequest{ParamsType: "voting"} + queryVoteParamsResp, err := s.Client.GovQueryClientV1.Params(ctx, &queryVoteParamsReq) + s.Require().NoError(err) + + // 5. wait a voting period and confirm that the proposal success. + s.T().Logf("voting period %s", *queryVoteParamsResp.Params.VotingPeriod) + time.Sleep(*queryVoteParamsResp.Params.VotingPeriod) + time.Sleep(1 * time.Second) + proposalRes, err := s.Client.GovQueryClientV1.Proposal(ctx, queryProposal) + s.Require().NoError(err) + s.Require().Equal(proposalRes.Proposal.Status, govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED) +} + +func (s *StorageTestSuite) TestSetBucketRateLimitToZero() { + s.enableMessage() + + 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, 10000000) + 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(0)) + s.SendTxBlock(s.User, msgSetBucketRateLimit) + + queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) + s.Require().Equal(queryHeadBucketResponse.ExtraInfo.FlowRateLimit.String(), "0") + + // 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.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit") +} + +// TestNotOwnerSetBucketRateLimit_Object +// 1. user create a bucket with 0 read quota +// 2. the payment account set the rate limit +// 3. user create an object in the bucket +// 4. the payment account set the rate limit to 0 +// 5. user create an object in the bucket and it should fail +// 6. the payment account set the rate limit to a positive number +// 7. user create an object in the bucket and it should pass +func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Object() { + s.enableMessage() + + var err error + sp := s.BaseSuite.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + user := s.User + paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] + + // CreateBucket + bucketName := storageutils.GenRandomBucketName() + + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), + paymentAcc.GetAddr(), 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, paymentAcc.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) + + // SetBucketRateLimit + msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) + s.SendTxBlock(paymentAcc, 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(user, msgCreateObject) + + // SetBucketRateLimit + msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) + s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) + + // CreateObject + objectName = storageutils.GenRandomObjectName() + 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.SendTxBlockWithExpectErrorString(msgCreateObject, user, "greater than the flow rate limit") + + // SetBucketRateLimit + msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) + s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) + + // create object + objectName = storageutils.GenRandomObjectName() + 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(user, msgCreateObject) +} + +// TestNotOwnerSetBucketRateLimit_Bucket +// 1. user create a bucket with 0 read quota +// 2. the payment account set the rate limit +// 3. user update the read quota to a positive number +// 4. the payment account set the rate limit to 0 +// 5. user update the read quota to a positive number and it should fail +// 6. the payment account set the rate limit to a positive number +// 7. user update the read quota to a positive number and it should pass +func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Bucket() { + s.enableMessage() + + var err error + sp := s.BaseSuite.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + user := s.User + paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] + + // CreateBucket + bucketName := storageutils.GenRandomBucketName() + + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), + paymentAcc.GetAddr(), 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, paymentAcc.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) + + // SetBucketRateLimit + msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000)) + s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) + + // UpdateBucketInfo + var readQuota uint64 = 100 + msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) + s.SendTxBlock(user, msgUpdateBucketInfo) + + // SetBucketRateLimit + msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) + s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) + + queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) + + // update bucket + readQuota = 101 + msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) + s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "payment account is not changed but the bucket is limited") + + // SetBucketRateLimit + msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000)) + s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) + + queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, false) + + // update bucket + readQuota = 102 + msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) + s.SendTxBlock(user, msgUpdateBucketInfo) +} + +// TestNotOwnerSetBucketRateLimit_BucketPaymentAccount +// 1. user create a bucket with positive read quota +// 2. user set the rate limit to 0 +// 3. update the payment account to another payment account, it should fail +// 4. the payment account set the rate limit to 0 +// 5. user update the payment account to another payment account, it should fail +// 6. the payment account set the rate limit to a positive number +// 7. user update the payment account to another payment account, it should pass +func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_BucketPaymentAccount() { + s.enableMessage() + + var err error + sp := s.BaseSuite.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + user := s.User + paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] + + // CreateBucket + bucketName := storageutils.GenRandomBucketName() + + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), + user.GetAddr(), math.MaxUint, nil, 100) + 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, s.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) + + // SetBucketRateLimit + msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(s.User.GetAddr(), s.User.GetAddr(), s.User.GetAddr(), bucketName, sdkmath.NewInt(0)) + s.SendTxBlock(s.User, msgSetBucketRateLimit) + + // SetBucketRateLimit + msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) + s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "the flow rate limit is not set") + + // SetBucketRateLimit + msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(0)) + s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) + + queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) + + // UpdateBucketInfo + msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) + s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "greater than the flow rate limit") + + // SetBucketRateLimit + msgSetBucketRateLimit = storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) + s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) + + // UpdateBucketInfo + msgUpdateBucketInfo = storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, nil, paymentAcc.GetAddr(), storagetypes.VISIBILITY_TYPE_PUBLIC_READ) + s.SendTxBlock(user, msgUpdateBucketInfo) + + queryHeadBucketRequest = storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + queryHeadBucketResponse, err = s.Client.HeadBucket(ctx, &queryHeadBucketRequest) + s.Require().NoError(err) + + s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, false) +} + +func (s *StorageTestSuite) TestQueryBucketRateLimit() { + s.enableMessage() + + var err error + sp := s.BaseSuite.PickStorageProvider() + gvg, found := sp.GetFirstGlobalVirtualGroup() + s.Require().True(found) + user := s.User + paymentAcc := s.GenAndChargeAccounts(1, 1000000)[0] + + // CreateBucket + bucketName := storageutils.GenRandomBucketName() + + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PUBLIC_READ, sp.OperatorKey.GetAddr(), + paymentAcc.GetAddr(), 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) + + // SetBucketRateLimit + msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(paymentAcc.GetAddr(), s.User.GetAddr(), paymentAcc.GetAddr(), bucketName, sdkmath.NewInt(100000000000000)) + s.SendTxBlock(paymentAcc, msgSetBucketRateLimit) + + // update bucket + var readQuota uint64 = 100 + msgUpdateBucketInfo := storagetypes.NewMsgUpdateBucketInfo( + user.GetAddr(), bucketName, &readQuota, nil, storagetypes.VISIBILITY_TYPE_PUBLIC_READ) + s.SendTxBlock(user, msgUpdateBucketInfo) + + s.Require().NoError(err) + + // QueryBucketRateLimit + ctx := context.Background() + queryBucketRateLimitRequest := storagetypes.QueryPaymentAccountBucketFlowRateLimitRequest{ + PaymentAccount: paymentAcc.GetAddr().String(), + BucketName: bucketName, + BucketOwner: user.GetAddr().String(), + } + queryBucketRateLimitResponse, err := s.Client.QueryPaymentAccountBucketFlowRateLimit(ctx, &queryBucketRateLimitRequest) + s.Require().NoError(err) + s.Require().Equal(queryBucketRateLimitResponse.IsSet, true) + s.Require().Equal(queryBucketRateLimitResponse.FlowRateLimit, sdkmath.NewInt(100000000000000)) +} diff --git a/x/storage/keeper/payment.go b/x/storage/keeper/payment.go index 37c044895..e4384a9a6 100644 --- a/x/storage/keeper/payment.go +++ b/x/storage/keeper/payment.go @@ -435,23 +435,45 @@ func (k Keeper) ChargeViaObjectChange(ctx sdk.Context, bucketInfo *storagetypes. userFlows.Flows = append(userFlows.Flows, newOutFlows...) if ctx.IsUpgraded(upgradetypes.Serengeti) { - currentBill, err := k.GetBucketReadStoreBill(ctx, bucketInfo, internalBucketInfo) - if err != nil { - return nil, fmt.Errorf("get bucket bill failed: %s %w", bucketInfo.BucketName, err) + var shouldApplyFlowRate = true + forced, _ := ctx.Value(types.ForceUpdateStreamRecordKey).(bool) + if forced { + isRateLimited := k.IsBucketRateLimited(ctx, bucketInfo.BucketName) + if isRateLimited { + // if the bucket is rate limited, no need to apply the flow rate since + // the bucket is already uncharged + shouldApplyFlowRate = false + } + } else { + // we should only check the flow rate limit when is not forced + currentBill, err := k.GetBucketReadStoreBill(ctx, bucketInfo, internalBucketInfo) + if err != nil { + return nil, fmt.Errorf("get bucket bill failed: %s %w", bucketInfo.BucketName, err) + } + + err = k.isBucketFlowRateUnderLimit(ctx, sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress), sdk.MustAccAddressFromHex(bucketInfo.Owner), bucketInfo.BucketName, currentBill) + if err != nil { + return nil, err + } } - err = k.isBucketFlowRateUnderLimit(ctx, sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress), sdk.MustAccAddressFromHex(bucketInfo.Owner), bucketInfo.BucketName, currentBill) + if shouldApplyFlowRate { + err = k.paymentKeeper.ApplyUserFlowsList(ctx, []types.UserFlows{userFlows}) + if err != nil { + ctx.Logger().Error("charge object store fee failed", "bucket", bucketInfo.BucketName, + "object", objectInfo.ObjectName, "err", err.Error()) + return nil, err + } + } + } else { + err = k.paymentKeeper.ApplyUserFlowsList(ctx, []types.UserFlows{userFlows}) if err != nil { + ctx.Logger().Error("charge object store fee failed", "bucket", bucketInfo.BucketName, + "object", objectInfo.ObjectName, "err", err.Error()) return nil, err } } - err = k.paymentKeeper.ApplyUserFlowsList(ctx, []types.UserFlows{userFlows}) - if err != nil { - ctx.Logger().Error("charge object store fee failed", "bucket", bucketInfo.BucketName, - "object", objectInfo.ObjectName, "err", err.Error()) - return nil, err - } // merge outflows for early deletion usage return k.paymentKeeper.MergeOutFlows(userFlows.Flows), nil } From 220ec828b377e7af5eb627536759b631b7b366a9 Mon Sep 17 00:00:00 2001 From: yutianwu Date: Mon, 1 Apr 2024 16:19:00 +0800 Subject: [PATCH 4/8] add test case --- e2e/tests/storage_rate_limit_test.go | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/e2e/tests/storage_rate_limit_test.go b/e2e/tests/storage_rate_limit_test.go index 9dec8bd46..ae18cbed9 100644 --- a/e2e/tests/storage_rate_limit_test.go +++ b/e2e/tests/storage_rate_limit_test.go @@ -482,3 +482,36 @@ func (s *StorageTestSuite) TestQueryBucketRateLimit() { s.Require().Equal(queryBucketRateLimitResponse.IsSet, true) s.Require().Equal(queryBucketRateLimitResponse.FlowRateLimit, sdkmath.NewInt(100000000000000)) } + +func (s *StorageTestSuite) TestSetBucketFlowRateLimit_Discontinue() { + sp, user, bucketName, _, _, _ := s.createObject() + + // SetBucketRateLimit + msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(user.GetAddr(), user.GetAddr(), user.GetAddr(), bucketName, sdkmath.NewInt(0)) + s.SendTxBlock(user, msgSetBucketRateLimit) + + queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + queryHeadBucketResponse, err := s.Client.HeadBucket(context.Background(), &queryHeadBucketRequest) + s.Require().NoError(err) + + s.Require().Equal(queryHeadBucketResponse.ExtraInfo.IsRateLimited, true) + + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") + txRes1 := s.SendTxBlock(sp.GcKey, msgDiscontinueBucket) + deleteAt1 := filterDiscontinueBucketEventFromTx(txRes1).DeleteAt + + for { + time.Sleep(200 * time.Millisecond) + statusRes, err := s.TmClient.TmClient.Status(context.Background()) + s.Require().NoError(err) + blockTime := statusRes.SyncInfo.LatestBlockTime.Unix() + + s.T().Logf("current blockTime: %d, delete blockTime: %d", blockTime, deleteAt1) + + if blockTime >= deleteAt1 { + break + } + } +} From 113e610dddf7192f85d4e4cf83b3204a78def790 Mon Sep 17 00:00:00 2001 From: yutianwu Date: Tue, 2 Apr 2024 10:20:25 +0800 Subject: [PATCH 5/8] create object with new gvg --- e2e/tests/storage_rate_limit_test.go | 131 ++++++++++++++++++++++++++- e2e/tests/storage_test.go | 23 +++++ 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/e2e/tests/storage_rate_limit_test.go b/e2e/tests/storage_rate_limit_test.go index ae18cbed9..caac1fcf7 100644 --- a/e2e/tests/storage_rate_limit_test.go +++ b/e2e/tests/storage_rate_limit_test.go @@ -14,6 +14,11 @@ import ( gashubtypes "github.com/cosmos/cosmos-sdk/x/gashub/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + "github.com/prysmaticlabs/prysm/crypto/bls" + + "github.com/bnb-chain/greenfield/e2e/core" + "github.com/bnb-chain/greenfield/sdk/keys" + virtualgrouptypes "github.com/bnb-chain/greenfield/x/virtualgroup/types" types2 "github.com/bnb-chain/greenfield/sdk/types" @@ -484,7 +489,9 @@ func (s *StorageTestSuite) TestQueryBucketRateLimit() { } func (s *StorageTestSuite) TestSetBucketFlowRateLimit_Discontinue() { - sp, user, bucketName, _, _, _ := s.createObject() + s.enableMessage() + + sp, user, bucketName, _, _, _ := s.createObjectWithNewGvg(storagetypes.VISIBILITY_TYPE_PRIVATE) // SetBucketRateLimit msgSetBucketRateLimit := storagetypes.NewMsgSetBucketFlowRateLimit(user.GetAddr(), user.GetAddr(), user.GetAddr(), bucketName, sdkmath.NewInt(0)) @@ -515,3 +522,125 @@ func (s *StorageTestSuite) TestSetBucketFlowRateLimit_Discontinue() { } } } + +func (s *StorageTestSuite) createObjectWithNewGvg(v storagetypes.VisibilityType) (*core.StorageProvider, keys.KeyManager, string, storagetypes.Uint, string, storagetypes.Uint) { + var err error + // CreateBucket + sp := s.BaseSuite.PickStorageProvider() + + _, secondarySps := s.GetSecondarySP(sp) + gvgID, _ := s.BaseSuite.CreateGlobalVirtualGroup(sp, 0, secondarySps, 1) + gvgResp, err := s.Client.VirtualGroupQueryClient.GlobalVirtualGroup(context.Background(), &virtualgrouptypes.QueryGlobalVirtualGroupRequest{ + GlobalVirtualGroupId: gvgID, + }) + s.Require().NoError(err) + gvg := gvgResp.GlobalVirtualGroup + + user := s.GenAndChargeAccounts(1, 1000000)[0] + bucketName := storageutils.GenRandomBucketName() + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, v, 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, v) + s.Require().Equal(queryHeadBucketResponse.BucketInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) + + // CreateObject + objectName := storageutils.GenRandomObjectName() + // create test buffer + var buffer bytes.Buffer + line := `1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890,1234567890, + 1234567890,1234567890,1234567890,123` + // 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), v, expectChecksum, contextType, storagetypes.REDUNDANCY_EC_TYPE, math.MaxUint, nil) + msgCreateObject.PrimarySpApproval.Sig, err = sp.ApprovalKey.Sign(msgCreateObject.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(user, msgCreateObject) + + // HeadObject + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectName, objectName) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.BucketName, bucketName) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.PayloadSize, uint64(payloadSize)) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.Visibility, v) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_CREATED) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.Owner, user.GetAddr().String()) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.Checksums, expectChecksum) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.SourceType, storagetypes.SOURCE_TYPE_ORIGIN) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.RedundancyType, storagetypes.REDUNDANCY_EC_TYPE) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ContentType, contextType) + + // SealObject + gvgId := gvg.Id + msgSealObject := storagetypes.NewMsgSealObject(sp.SealKey.GetAddr(), bucketName, objectName, gvgId, 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) + + // ListBuckets + queryListBucketsRequest := storagetypes.QueryListBucketsRequest{} + queryListBucketResponse, err := s.Client.ListBuckets(ctx, &queryListBucketsRequest) + s.Require().NoError(err) + s.Require().Greater(len(queryListBucketResponse.BucketInfos), 0) + + // ListObject + queryListObjectsRequest := storagetypes.QueryListObjectsRequest{ + BucketName: bucketName, + } + queryListObjectsResponse, err := s.Client.ListObjects(ctx, &queryListObjectsRequest) + s.Require().NoError(err) + s.Require().Equal(len(queryListObjectsResponse.ObjectInfos), 1) + s.Require().Equal(queryListObjectsResponse.ObjectInfos[0].ObjectName, objectName) + return sp, user, bucketName, queryHeadBucketResponse.BucketInfo.Id, objectName, queryListObjectsResponse.ObjectInfos[0].Id +} diff --git a/e2e/tests/storage_test.go b/e2e/tests/storage_test.go index 63ee84549..edf571650 100644 --- a/e2e/tests/storage_test.go +++ b/e2e/tests/storage_test.go @@ -985,6 +985,29 @@ func (s *StorageTestSuite) TestDiscontinueBucket_UserDeleted() { s.Require().True(statusRes.SyncInfo.LatestBlockHeight > heightAfter) } +func (s *StorageTestSuite) GetSecondarySP(sps ...*core.StorageProvider) ([]*core.StorageProvider, []uint32) { + var secondarySPs []*core.StorageProvider + var secondarySPIDs []uint32 + + for _, ssp := range s.StorageProviders { + isSecondSP := true + for _, sp := range sps { + if ssp.Info.Id == sp.Info.Id { + isSecondSP = false + break + } + } + if isSecondSP { + secondarySPIDs = append(secondarySPIDs, ssp.Info.Id) + secondarySPs = append(secondarySPs, ssp) + } + if len(secondarySPIDs) == 6 { + break + } + } + return secondarySPs, secondarySPIDs +} + // createObject with default VISIBILITY_TYPE_PRIVATE func (s *StorageTestSuite) createObject() (*core.StorageProvider, keys.KeyManager, string, storagetypes.Uint, string, storagetypes.Uint) { return s.createObjectWithVisibility(storagetypes.VISIBILITY_TYPE_PRIVATE) From 8c5e2f567e437fb04a7929de24c858b93d5e1529 Mon Sep 17 00:00:00 2001 From: yutianwu Date: Tue, 2 Apr 2024 11:44:59 +0800 Subject: [PATCH 6/8] introduce erdos upgrade --- app/upgrade.go | 19 +++++++++++++++++++ deployment/localup/localup.sh | 1 + e2e/tests/storage_rate_limit_test.go | 14 +------------- go.mod | 2 +- go.sum | 4 ++-- x/storage/keeper/keeper.go | 2 +- x/storage/keeper/payment.go | 14 +++++++------- x/storage/keeper/verify.go | 2 +- 8 files changed, 33 insertions(+), 25 deletions(-) diff --git a/app/upgrade.go b/app/upgrade.go index cc1dc0bf2..67bc5eef5 100644 --- a/app/upgrade.go +++ b/app/upgrade.go @@ -31,6 +31,7 @@ func (app *App) RegisterUpgradeHandlers(chainID string, serverCfg *serverconfig. app.registerUralUpgradeHandler() app.registerPawneeUpgradeHandler() app.registerSerengetiUpgradeHandler() + app.registerErdosUpgradeHandler() // app.register...() // ... return nil @@ -237,3 +238,21 @@ func (app *App) registerSerengetiUpgradeHandler() { return nil }) } + +func (app *App) registerErdosUpgradeHandler() { + // Register the upgrade handler + app.UpgradeKeeper.SetUpgradeHandler(upgradetypes.Erdos, + func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + app.Logger().Info("upgrade to ", plan.Name) + app.VirtualgroupKeeper.MigrateGlobalVirtualGroupFamiliesForSP(ctx) + app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgSetBucketFlowRateLimit{}), 1.2e2)) + return app.mm.RunMigrations(ctx, app.configurator, fromVM) + }) + + // Register the upgrade initializer + app.UpgradeKeeper.SetUpgradeInitializer(upgradetypes.Erdos, + func() error { + app.Logger().Info("Init Erdos upgrade") + return nil + }) +} diff --git a/deployment/localup/localup.sh b/deployment/localup/localup.sh index 5553b9ea1..bbdc9d9bd 100644 --- a/deployment/localup/localup.sh +++ b/deployment/localup/localup.sh @@ -179,6 +179,7 @@ function generate_genesis() { echo -e '[[upgrade]]\nname = "Ural"\nheight = 22\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml 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 done # enable swagger API for validator0 diff --git a/e2e/tests/storage_rate_limit_test.go b/e2e/tests/storage_rate_limit_test.go index caac1fcf7..b8468ef02 100644 --- a/e2e/tests/storage_rate_limit_test.go +++ b/e2e/tests/storage_rate_limit_test.go @@ -18,12 +18,10 @@ import ( "github.com/bnb-chain/greenfield/e2e/core" "github.com/bnb-chain/greenfield/sdk/keys" - virtualgrouptypes "github.com/bnb-chain/greenfield/x/virtualgroup/types" - types2 "github.com/bnb-chain/greenfield/sdk/types" - storageutils "github.com/bnb-chain/greenfield/testutil/storage" storagetypes "github.com/bnb-chain/greenfield/x/storage/types" + virtualgrouptypes "github.com/bnb-chain/greenfield/x/virtualgroup/types" ) func (s *StorageTestSuite) enableMessage() { @@ -87,8 +85,6 @@ func (s *StorageTestSuite) enableMessage() { } func (s *StorageTestSuite) TestSetBucketRateLimitToZero() { - s.enableMessage() - var err error sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() @@ -262,8 +258,6 @@ func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Object() { // 6. the payment account set the rate limit to a positive number // 7. user update the read quota to a positive number and it should pass func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Bucket() { - s.enableMessage() - var err error sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() @@ -358,8 +352,6 @@ func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_Bucket() { // 6. the payment account set the rate limit to a positive number // 7. user update the payment account to another payment account, it should pass func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_BucketPaymentAccount() { - s.enableMessage() - var err error sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() @@ -443,8 +435,6 @@ func (s *StorageTestSuite) TestNotOwnerSetBucketRateLimit_BucketPaymentAccount() } func (s *StorageTestSuite) TestQueryBucketRateLimit() { - s.enableMessage() - var err error sp := s.BaseSuite.PickStorageProvider() gvg, found := sp.GetFirstGlobalVirtualGroup() @@ -489,8 +479,6 @@ func (s *StorageTestSuite) TestQueryBucketRateLimit() { } func (s *StorageTestSuite) TestSetBucketFlowRateLimit_Discontinue() { - s.enableMessage() - sp, user, bucketName, _, _, _ := s.createObjectWithNewGvg(storagetypes.VISIBILITY_TYPE_PRIVATE) // SetBucketRateLimit diff --git a/go.mod b/go.mod index ffdc5452e..5f01237ad 100644 --- a/go.mod +++ b/go.mod @@ -179,7 +179,7 @@ replace ( github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v1.2.0 github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1 github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240314024318-a972393c0430 + github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240402031746-d46857cfafc0 github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/wercker/journalhook => github.com/wercker/journalhook v0.0.0-20230927020745-64542ffa4117 diff --git a/go.sum b/go.sum index 74f8c9031..aceab18b2 100644 --- a/go.sum +++ b/go.sum @@ -163,8 +163,8 @@ github.com/bnb-chain/greenfield-cometbft v1.2.0 h1:LTStppZS9WkVj0TfEYKkk5OAQDGfY github.com/bnb-chain/greenfield-cometbft v1.2.0/go.mod h1:WVOEZ59UYM2XePQH47/IQfcInspDn8wbRXhFSJrbU1c= github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1 h1:XcWulGacHVRiSCx90Q8Y//ajOrLNBQWR/KDB89dy3cU= github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1/go.mod h1:ey1CiK4bYo1RBNJLRiVbYr5CMdSxci9S/AZRINLtppI= -github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240314024318-a972393c0430 h1:Lerm4iJITbmJBOqRj/IPQhS8cvjTKOfuq3XOoDgjAtM= -github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240314024318-a972393c0430/go.mod h1:XF8U3VN1euzLkIR5xiSNyQSnBabvnD86oz6fgdrpteQ= +github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240402031746-d46857cfafc0 h1:Cm9EWuktgeyYotoL6ef0XpqB2ECjIzDwQxqFmgfPjTM= +github.com/bnb-chain/greenfield-cosmos-sdk v1.5.1-0.20240402031746-d46857cfafc0/go.mod h1:XF8U3VN1euzLkIR5xiSNyQSnBabvnD86oz6fgdrpteQ= github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210 h1:GHPbV2bC+gmuO6/sG0Tm8oGal3KKSRlyE+zPscDjlA8= github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210/go.mod h1:vhsZxXE9tYJeYB5JR4hPhd6Pc/uPf7j1T8IJ7p9FdeM= github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230816082903-b48770f5e210 h1:FLVOn4+OVbsKi2+YJX5kmD27/4dRu4FW7xCXFhzDO5s= diff --git a/x/storage/keeper/keeper.go b/x/storage/keeper/keeper.go index 3225a521c..3b30ff330 100644 --- a/x/storage/keeper/keeper.go +++ b/x/storage/keeper/keeper.go @@ -270,7 +270,7 @@ func (k Keeper) doDeleteBucket(ctx sdk.Context, operator sdk.AccAddress, bucketI } } - if ctx.IsUpgraded(upgradetypes.Serengeti) { + if ctx.IsUpgraded(upgradetypes.Erdos) { // delete bucket flow rate limit status k.deleteBucketFlowRateLimitStatus(ctx, bucketInfo.BucketName, bucketInfo.Id) } diff --git a/x/storage/keeper/payment.go b/x/storage/keeper/payment.go index e4384a9a6..462359a3f 100644 --- a/x/storage/keeper/payment.go +++ b/x/storage/keeper/payment.go @@ -25,7 +25,7 @@ func (k Keeper) ChargeBucketReadFee(ctx sdk.Context, bucketInfo *storagetypes.Bu return fmt.Errorf("charge bucket read fee failed, get bucket bill failed: %s %s", bucketInfo.BucketName, err.Error()) } - if ctx.IsUpgraded(upgradetypes.Serengeti) { + if ctx.IsUpgraded(upgradetypes.Erdos) { err := k.isBucketFlowRateUnderLimit(ctx, sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress), sdk.MustAccAddressFromHex(bucketInfo.Owner), bucketInfo.BucketName, bill) if err != nil { return err @@ -46,7 +46,7 @@ func (k Keeper) UnChargeBucketReadFee(ctx sdk.Context, bucketInfo *storagetypes. return fmt.Errorf("unexpected total store charge size: %s, %d", bucketInfo.BucketName, internalBucketInfo.TotalChargeSize) } - if ctx.IsUpgraded(upgradetypes.Serengeti) { + if ctx.IsUpgraded(upgradetypes.Erdos) { // if the bucket's flow rate limit is set to zero, no need to uncharge, since the bucket is already uncharged if k.IsBucketRateLimited(ctx, bucketInfo.BucketName) { return nil @@ -145,7 +145,7 @@ func (k Keeper) lockObjectStoreFee(ctx sdk.Context, bucketInfo *storagetypes.Buc }) } - if ctx.IsUpgraded(upgradetypes.Serengeti) && k.shouldCheckRateLimit(ctx, paymentAddr, sdk.MustAccAddressFromHex(bucketInfo.Owner), bucketInfo.BucketName) { + if ctx.IsUpgraded(upgradetypes.Erdos) && k.shouldCheckRateLimit(ctx, paymentAddr, sdk.MustAccAddressFromHex(bucketInfo.Owner), bucketInfo.BucketName) { internalBucketInfo := k.MustGetInternalBucketInfo(ctx, bucketInfo.Id) internalBucketInfo.PriceTime = timestamp nextBill, err := k.GetBucketReadStoreBill(ctx, bucketInfo, internalBucketInfo) @@ -346,7 +346,7 @@ func (k Keeper) ChargeViaBucketChange(ctx sdk.Context, bucketInfo *storagetypes. return fmt.Errorf("get new bucket bill failed: %s %w", bucketInfo.BucketName, err) } - if ctx.IsUpgraded(upgradetypes.Serengeti) { + if ctx.IsUpgraded(upgradetypes.Erdos) { isPreviousBucketLimited := k.IsBucketRateLimited(ctx, bucketInfo.BucketName) if prevPaymentAccount == bucketInfo.PaymentAddress && isPreviousBucketLimited { @@ -434,7 +434,7 @@ func (k Keeper) ChargeViaObjectChange(ctx sdk.Context, bucketInfo *storagetypes. userFlows.Flows = append(userFlows.Flows, getNegFlows(preOutFlows)...) userFlows.Flows = append(userFlows.Flows, newOutFlows...) - if ctx.IsUpgraded(upgradetypes.Serengeti) { + if ctx.IsUpgraded(upgradetypes.Erdos) { var shouldApplyFlowRate = true forced, _ := ctx.Value(types.ForceUpdateStreamRecordKey).(bool) if forced { @@ -570,7 +570,7 @@ func (k Keeper) GetBucketReadStoreBill(ctx sdk.Context, bucketInfo *storagetypes func (k Keeper) UnChargeBucketReadStoreFee(ctx sdk.Context, bucketInfo *storagetypes.BucketInfo, internalBucketInfo *storagetypes.InternalBucketInfo) error { - if ctx.IsUpgraded(upgradetypes.Serengeti) { + if ctx.IsUpgraded(upgradetypes.Erdos) { // if the bucket's flow rate limit is set to zero, no need to uncharge, since the bucket is already uncharged if k.IsBucketRateLimited(ctx, bucketInfo.BucketName) { return nil @@ -597,7 +597,7 @@ func (k Keeper) ChargeBucketReadStoreFee(ctx sdk.Context, bucketInfo *storagetyp return fmt.Errorf("get bucket bill failed: %s %s", bucketInfo.BucketName, err.Error()) } - if ctx.IsUpgraded(upgradetypes.Serengeti) { + if ctx.IsUpgraded(upgradetypes.Erdos) { err := k.isBucketFlowRateUnderLimit(ctx, sdk.MustAccAddressFromHex(bucketInfo.PaymentAddress), sdk.MustAccAddressFromHex(bucketInfo.Owner), bucketInfo.BucketName, bill) if err != nil { return err diff --git a/x/storage/keeper/verify.go b/x/storage/keeper/verify.go index 36f5072ee..2b4dd7001 100644 --- a/x/storage/keeper/verify.go +++ b/x/storage/keeper/verify.go @@ -16,7 +16,7 @@ func (k Keeper) VerifyPaymentAccount(ctx sdk.Context, paymentAddress string, own } // don't check if the payment account is owned by the owner account - if !ctx.IsUpgraded(upgradetypes.Serengeti) { + if !ctx.IsUpgraded(upgradetypes.Erdos) { if !k.paymentKeeper.IsPaymentAccountOwner(ctx, paymentAcc, ownerAcc) { return nil, paymenttypes.ErrNotPaymentAccountOwner } From cd3fe09bb3b336591b052d17707dd895495de744 Mon Sep 17 00:00:00 2001 From: yutianwu Date: Tue, 2 Apr 2024 13:57:14 +0800 Subject: [PATCH 7/8] update gas price --- app/upgrade.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/upgrade.go b/app/upgrade.go index 67bc5eef5..2a20eb54a 100644 --- a/app/upgrade.go +++ b/app/upgrade.go @@ -245,7 +245,7 @@ func (app *App) registerErdosUpgradeHandler() { func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { app.Logger().Info("upgrade to ", plan.Name) app.VirtualgroupKeeper.MigrateGlobalVirtualGroupFamiliesForSP(ctx) - app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgSetBucketFlowRateLimit{}), 1.2e2)) + app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgSetBucketFlowRateLimit{}), 1.2e3)) return app.mm.RunMigrations(ctx, app.configurator, fromVM) }) From bdd78c205ba6379bd441a4e0f0ecb6ee0bd928eb Mon Sep 17 00:00:00 2001 From: yutianwu Date: Tue, 2 Apr 2024 14:31:45 +0800 Subject: [PATCH 8/8] remove unused code --- app/upgrade.go | 1 - 1 file changed, 1 deletion(-) diff --git a/app/upgrade.go b/app/upgrade.go index 2a20eb54a..c83d0ba79 100644 --- a/app/upgrade.go +++ b/app/upgrade.go @@ -244,7 +244,6 @@ func (app *App) registerErdosUpgradeHandler() { app.UpgradeKeeper.SetUpgradeHandler(upgradetypes.Erdos, func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { app.Logger().Info("upgrade to ", plan.Name) - app.VirtualgroupKeeper.MigrateGlobalVirtualGroupFamiliesForSP(ctx) app.GashubKeeper.SetMsgGasParams(ctx, *gashubtypes.NewMsgGasParamsWithFixedGas(sdk.MsgTypeURL(&storagemoduletypes.MsgSetBucketFlowRateLimit{}), 1.2e3)) return app.mm.RunMigrations(ctx, app.configurator, fromVM) })