From f7b27140f910f3900a739067a6b7d3d20ffac2c9 Mon Sep 17 00:00:00 2001 From: forcodedancing Date: Tue, 8 Aug 2023 18:54:40 +0800 Subject: [PATCH] update sp module --- app/export_test.go | 5 +- deployment/localup/localup.sh | 2 + e2e/core/basesuite.go | 2 +- e2e/tests/payment_test.go | 3 +- e2e/tests/storage_bill_test.go | 375 ++++++++++++++++++++++-- e2e/tests/storage_test.go | 3 +- proto/greenfield/sp/params.proto | 4 + swagger/static/swagger.yaml | 256 +++++++++------- x/bridge/client/cli/tx_test.go | 4 +- x/challenge/client/cli/query_test.go | 2 +- x/payment/client/cli/query_test.go | 2 +- x/permission/client/cli/query_test.go | 2 +- x/sp/abci.go | 14 +- x/sp/client/cli/query_test.go | 2 +- x/sp/keeper/msg_server.go | 17 +- x/sp/keeper/sp_status.go | 3 +- x/sp/keeper/sp_storage_price.go | 33 +++ x/sp/types/errors.go | 1 + x/sp/types/keys.go | 25 +- x/sp/types/params.go | 46 ++- x/sp/types/params.pb.go | 146 +++++++-- x/storage/client/cli/query_test.go | 2 +- x/storage/keeper/keeper_test.go | 4 +- x/storage/keeper/payment.go | 3 +- x/virtualgroup/client/cli/query_test.go | 2 +- 25 files changed, 740 insertions(+), 218 deletions(-) diff --git a/app/export_test.go b/app/export_test.go index a9c3cd26a..6982c7fab 100644 --- a/app/export_test.go +++ b/app/export_test.go @@ -3,11 +3,12 @@ package app_test import ( "testing" - "github.com/bnb-chain/greenfield/sdk/client/test" - "github.com/bnb-chain/greenfield/testutil" dbm "github.com/cometbft/cometbft-db" "github.com/cometbft/cometbft/libs/log" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/bnb-chain/greenfield/sdk/client/test" + "github.com/bnb-chain/greenfield/testutil" ) func TestExportAppStateAndValidators(t *testing.T) { diff --git a/deployment/localup/localup.sh b/deployment/localup/localup.sh index bda54bdcf..88606177c 100644 --- a/deployment/localup/localup.sh +++ b/deployment/localup/localup.sh @@ -153,6 +153,8 @@ function generate_genesis() { sed -i -e "s/\"discontinue_confirm_period\": \"604800\"/\"discontinue_confirm_period\": \"5\"/g" ${workspace}/.local/validator${i}/config/genesis.json sed -i -e "s/\"discontinue_deletion_max\": \"100\"/\"discontinue_deletion_max\": \"2\"/g" ${workspace}/.local/validator${i}/config/genesis.json sed -i -e "s/\"voting_period\": \"30s\"/\"voting_period\": \"5s\"/g" ${workspace}/.local/validator${i}/config/genesis.json + sed -i -e "s/\"update_global_price_interval\": \"2592000\"/\"update_global_price_interval\": \"1\"/g" ${workspace}/.local/validator${i}/config/genesis.json + sed -i -e "s/\"max_update_price_times\": 3/\"max_update_price_times\": 1000000/g" ${workspace}/.local/validator${i}/config/genesis.json #sed -i -e "s/\"community_tax\": \"0.020000000000000000\"/\"community_tax\": \"0\"/g" ${workspace}/.local/validator${i}/config/genesis.json sed -i -e "s/log_level = \"info\"/\log_level= \"debug\"/g" ${workspace}/.local/validator${i}/config/config.toml done diff --git a/e2e/core/basesuite.go b/e2e/core/basesuite.go index 416c6cce8..107f6f677 100644 --- a/e2e/core/basesuite.go +++ b/e2e/core/basesuite.go @@ -127,7 +127,7 @@ func (s *BaseSuite) InitChain() { func (s *BaseSuite) SetupSuite() { s.Config = InitConfig() initValidatorOnce.Do(func() { - s.InitChain() + //s.InitChain() }) s.Client, _ = client.NewGreenfieldClient(s.Config.TendermintAddr, s.Config.ChainId) diff --git a/e2e/tests/payment_test.go b/e2e/tests/payment_test.go index 16b5774eb..a60c7727d 100644 --- a/e2e/tests/payment_test.go +++ b/e2e/tests/payment_test.go @@ -10,10 +10,9 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/types/query" - sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" diff --git a/e2e/tests/storage_bill_test.go b/e2e/tests/storage_bill_test.go index 6d5d5fabc..ab8c9febb 100644 --- a/e2e/tests/storage_bill_test.go +++ b/e2e/tests/storage_bill_test.go @@ -1593,13 +1593,13 @@ func (s *PaymentTestSuite) TestStorageBill_UpdateBucketQuota() { s.Require().NoError(err) // check price and rate calculation - priceRes, err := s.Client.QuerySpStoragePrice(ctx, &sptypes.QuerySpStoragePriceRequest{ - SpAddr: sp.OperatorKey.GetAddr().String(), + priceRes, err := s.Client.QueryGlobalSpStorePriceByTime(ctx, &sptypes.QueryGlobalSpStorePriceByTimeRequest{ + Timestamp: bucketInfo.CreateAt, }) s.T().Logf("priceRes %s, err: %v", priceRes, err) s.Require().NoError(err) - readPrice := priceRes.SpStoragePrice.ReadPrice + readPrice := priceRes.GlobalSpStorePrice.ReadPrice readChargeRate := readPrice.MulInt(sdk.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) taxRate := paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() @@ -1626,11 +1626,14 @@ func (s *PaymentTestSuite) TestStorageBill_UpdateBucketQuota() { }) s.Require().Equal(expectedOutFlows, userOutFlowsResponse.OutFlows) // update new price + spPriceRes, _ := s.Client.QuerySpStoragePrice(ctx, &sptypes.QuerySpStoragePriceRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + }) msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ SpAddress: sp.OperatorKey.GetAddr().String(), - ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(100), - FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, - StorePrice: priceRes.SpStoragePrice.StorePrice, + ReadPrice: spPriceRes.SpStoragePrice.ReadPrice.MulInt64(100), + FreeReadQuota: spPriceRes.SpStoragePrice.FreeReadQuota, + StorePrice: spPriceRes.SpStoragePrice.StorePrice, } s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) @@ -1639,13 +1642,13 @@ func (s *PaymentTestSuite) TestStorageBill_UpdateBucketQuota() { s.Require().NoError(err) // check price and rate calculation - priceRes, err = s.Client.QuerySpStoragePrice(ctx, &sptypes.QuerySpStoragePriceRequest{ - SpAddr: sp.OperatorKey.GetAddr().String(), + priceRes, err = s.Client.QueryGlobalSpStorePriceByTime(ctx, &sptypes.QueryGlobalSpStorePriceByTimeRequest{ + Timestamp: bucketInfo.CreateAt, }) s.T().Logf("priceRes %s, err: %v", priceRes, err) s.Require().NoError(err) - readPrice = priceRes.SpStoragePrice.ReadPrice + readPrice = priceRes.GlobalSpStorePrice.ReadPrice readChargeRate = readPrice.MulInt(sdk.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) taxRate = paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() @@ -1674,9 +1677,9 @@ func (s *PaymentTestSuite) TestStorageBill_UpdateBucketQuota() { // set big read price msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ SpAddress: sp.OperatorKey.GetAddr().String(), - ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(1024 * 1024 * 1024), - FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, - StorePrice: priceRes.SpStoragePrice.StorePrice, + ReadPrice: spPriceRes.SpStoragePrice.ReadPrice.MulInt64(1024 * 1024 * 1024), + FreeReadQuota: spPriceRes.SpStoragePrice.FreeReadQuota, + StorePrice: spPriceRes.SpStoragePrice.StorePrice, } s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) @@ -1685,7 +1688,6 @@ func (s *PaymentTestSuite) TestStorageBill_UpdateBucketQuota() { user.GetAddr(), bucketName, &chargedReadQuota, user.GetAddr(), storagetypes.VISIBILITY_TYPE_PRIVATE) s.reduceBNBBalance(user, s.Validator, sdkmath.NewIntWithDecimal(1, 16)) s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "apply user flows list failed") - } // TestStorageBill_UpdatePaymentAddress @@ -1740,13 +1742,13 @@ func (s *PaymentTestSuite) TestStorageBill_UpdatePaymentAddress() { s.Require().NoError(err) // check price and rate calculation - priceRes, err := s.Client.QuerySpStoragePrice(ctx, &sptypes.QuerySpStoragePriceRequest{ - SpAddr: sp.OperatorKey.GetAddr().String(), + priceRes, err := s.Client.QueryGlobalSpStorePriceByTime(ctx, &sptypes.QueryGlobalSpStorePriceByTimeRequest{ + Timestamp: bucketInfo.CreateAt, }) s.T().Logf("priceRes %s, err: %v", priceRes, err) s.Require().NoError(err) - readPrice := priceRes.SpStoragePrice.ReadPrice + readPrice := priceRes.GlobalSpStorePrice.ReadPrice readChargeRate := readPrice.MulInt(sdk.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) taxRate := paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() @@ -1756,7 +1758,7 @@ func (s *PaymentTestSuite) TestStorageBill_UpdatePaymentAddress() { streamRecordsAfter = s.getStreamRecords(streamAddresses) s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) - s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), readChargeRate) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), readChargeRate.Int64()) s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) expectedOutFlows := []paymenttypes.OutFlow{ @@ -1773,11 +1775,14 @@ func (s *PaymentTestSuite) TestStorageBill_UpdatePaymentAddress() { }) s.Require().Equal(expectedOutFlows, userOutFlowsResponse.OutFlows) // update new price + spPriceRes, _ := s.Client.QuerySpStoragePrice(ctx, &sptypes.QuerySpStoragePriceRequest{ + SpAddr: sp.OperatorKey.GetAddr().String(), + }) msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{ SpAddress: sp.OperatorKey.GetAddr().String(), - ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(100), - FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, - StorePrice: priceRes.SpStoragePrice.StorePrice, + ReadPrice: spPriceRes.SpStoragePrice.ReadPrice.MulInt64(100), + FreeReadQuota: spPriceRes.SpStoragePrice.FreeReadQuota, + StorePrice: spPriceRes.SpStoragePrice.StorePrice, } s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) @@ -1786,13 +1791,13 @@ func (s *PaymentTestSuite) TestStorageBill_UpdatePaymentAddress() { s.Require().NoError(err) // check price and rate calculation - priceRes, err = s.Client.QuerySpStoragePrice(ctx, &sptypes.QuerySpStoragePriceRequest{ - SpAddr: sp.OperatorKey.GetAddr().String(), + priceRes, err = s.Client.QueryGlobalSpStorePriceByTime(ctx, &sptypes.QueryGlobalSpStorePriceByTimeRequest{ + Timestamp: bucketInfo.CreateAt, }) s.T().Logf("priceRes %s, err: %v", priceRes, err) s.Require().NoError(err) - readPrice = priceRes.SpStoragePrice.ReadPrice + readPrice = priceRes.GlobalSpStorePrice.ReadPrice readChargeRate = readPrice.MulInt(sdk.NewIntFromUint64(bucketInfo.ChargedReadQuota)).TruncateInt() s.T().Logf("readPrice: %s, readChargeRate: %s", readPrice, readChargeRate) taxRate = paymentParams.Params.VersionedParams.ValidatorTaxRate.MulInt(readChargeRate).TruncateInt() @@ -1823,9 +1828,9 @@ func (s *PaymentTestSuite) TestStorageBill_UpdatePaymentAddress() { // set big read price msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{ SpAddress: sp.OperatorKey.GetAddr().String(), - ReadPrice: priceRes.SpStoragePrice.ReadPrice.MulInt64(1024 * 1024 * 1024), - FreeReadQuota: priceRes.SpStoragePrice.FreeReadQuota, - StorePrice: priceRes.SpStoragePrice.StorePrice, + ReadPrice: spPriceRes.SpStoragePrice.ReadPrice.MulInt64(1024 * 1024 * 1024), + FreeReadQuota: spPriceRes.SpStoragePrice.FreeReadQuota, + StorePrice: spPriceRes.SpStoragePrice.StorePrice, } s.SendTxBlock(sp.OperatorKey, msgUpdatePrice) @@ -1842,7 +1847,7 @@ func (s *PaymentTestSuite) TestStorageBill_UpdatePaymentAddress() { s.SendTxBlockWithExpectErrorString(msgUpdateBucketInfo, user, "apply user flows list failed") } -func (s *PaymentTestSuite) TestStorageBill_MigrationBucket() { +func (s *PaymentTestSuite) TestStorageBill_MigrateBucket() { var err error ctx := context.Background() primarySP := s.PickStorageProvider() @@ -1998,6 +2003,314 @@ func (s *PaymentTestSuite) TestStorageBill_MigrationBucket() { s.Require().Equal(streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Abs()) } +func (s *PaymentTestSuite) TestStorageBill_MigrateBucket_ThenDiscontinueBucket() { + var err error + ctx := context.Background() + primarySP := s.PickStorageProvider() + s.SetSPPrice(primarySP, "1", "1.15") + + gvg, found := primarySP.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + user := s.GenAndChargeAccounts(1, 10)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) + s.T().Logf("paymentParams %s, err: %v", paymentParams, err) + s.Require().NoError(err) + + bucketName := s.createBucket(primarySP, user, 0) + bucketInfo, err := s.Client.HeadBucket(context.Background(), &storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + }) + s.Require().NoError(err) + + // create object with none zero payload size + streamRecordsBefore := s.getStreamRecords(streamAddresses) + _, _, objectName, objectId, checksums, payloadSize := s.createObject(user, bucketName, false) + + // assertions + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + lockFee := s.calculateLockFee(primarySP, bucketName, objectName, payloadSize) + s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0)) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0)) + + // case: seal object + s.sealObject(primarySP, gvg, bucketName, objectName, objectId, checksums) + + // assertions + streamRecordsAfter = s.getStreamRecords(streamAddresses) + gvgFamilyRate, gvgRate, taxRate, userTotalRate := s.calculateStorageRates(primarySP, bucketName, objectName, payloadSize, 0) + s.T().Logf("gvgFamilyRate: %v, gvgRate: %v, taxRate: %v, userTotalRate: %v", gvgFamilyRate, gvgRate, taxRate, userTotalRate) + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Sub(streamRecordsBefore.User.NetflowRate), userTotalRate.Neg()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + taxRate0 := taxRate + dstPrimarySP := s.CreateNewStorageProvider() + + // create a new object without seal + s.createObject(user, bucketName, false) + + s.SetSPPrice(dstPrimarySP, "2", "1.45") + _, secondarySPIDs := s.GetSecondarySP(dstPrimarySP, primarySP) + gvgID, _ := s.BaseSuite.CreateGlobalVirtualGroup(dstPrimarySP, 0, secondarySPIDs, 1) + gvgResp, err := s.Client.VirtualGroupQueryClient.GlobalVirtualGroup(context.Background(), &virtualgrouptypes.QueryGlobalVirtualGroupRequest{ + GlobalVirtualGroupId: gvgID, + }) + s.Require().NoError(err) + dstGVG := gvgResp.GlobalVirtualGroup + s.Require().True(found) + + queryFamilyResponse, err = s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: dstGVG.FamilyId, + }) + s.Require().NoError(err) + family = queryFamilyResponse.GlobalVirtualGroupFamily + streamAddresses = []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + dstGVG.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + fundAddress := primarySP.FundingKey.GetAddr() + streamRecordsBefore = s.getStreamRecords(streamAddresses) + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: fundAddress.String()} + fundBalanceBefore, err := s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + + // MigrateBucket + msgMigrateBucket, msgCompleteMigrateBucket := s.NewMigrateBucket(primarySP, dstPrimarySP, user, bucketName, gvg.FamilyId, dstGVG.FamilyId, bucketInfo.BucketInfo.Id) + s.SendTxBlock(user, msgMigrateBucket) + s.Require().NoError(err) + + // complete MigrateBucket + s.SendTxBlock(dstPrimarySP.OperatorKey, msgCompleteMigrateBucket) + streamRecordsAfter = s.getStreamRecords(streamAddresses) + fundBalanceAfter, err := s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + s.T().Logf("fundBalanceBefore: %v, fundBalanceAfter: %v, diff: %v", fundBalanceBefore, fundBalanceAfter, fundBalanceAfter.Balance.Amount.Sub(fundBalanceBefore.Balance.Amount)) + s.Require().True(fundBalanceAfter.Balance.Amount.Sub(fundBalanceBefore.Balance.Amount).GT(sdkmath.NewInt(0)), "migrate sp fund address need settle") + gvgFamilyRate, gvgRate, taxRate, userTotalRate = s.calculateStorageRates(dstPrimarySP, bucketName, objectName, payloadSize, time.Now().Unix()) + s.T().Logf("gvgFamilyRate: %v, gvgRate: %v, taxRate: %v, userTotalRate: %v", gvgFamilyRate, gvgRate, taxRate, userTotalRate) + s.T().Logf("NetflowRate: %v, userTotalRate: %v, actual taxRate diff: %v, expect taxRate diff: %v", streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Neg(), streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate.Sub(taxRate0)) + + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate) + // tax rate diff + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate.Sub(taxRate0)) + s.Require().Equal(streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Abs()) + + // force delete bucket + headBucketResp, _ := s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.T().Log("headBucketResp", core.YamlString(headBucketResp)) + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(dstPrimarySP.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(dstPrimarySP.GcKey, msgDiscontinueBucket) + deleteAt := filterDiscontinueBucketEventFromTx(txRes).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, deleteAt) + + if blockTime > deleteAt { + break + } + } + + _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.Require().ErrorContains(err, "No such bucket") +} + +func (s *PaymentTestSuite) TestStorageBill_MigrateBucket_FrozenAccount_ThenDiscontinueBucket() { + var err error + ctx := context.Background() + primarySP := s.PickStorageProvider() + s.SetSPPrice(primarySP, "1", "1.15") + + gvg, found := primarySP.GetFirstGlobalVirtualGroup() + s.Require().True(found) + queryFamilyResponse, err := s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: gvg.FamilyId, + }) + s.Require().NoError(err) + s.T().Log("queryFamilyResponse", core.YamlString(queryFamilyResponse)) + user := s.GenAndChargeAccounts(1, 10)[0] + + bucketChargedReadQuota := uint64(1000) + params := s.queryParams() + reserveTime := params.VersionedParams.ReserveTime + queryGetSpStoragePriceByTimeResp, err := s.Client.QueryGlobalSpStorePriceByTime(ctx, &sptypes.QueryGlobalSpStorePriceByTimeRequest{ + Timestamp: 0, + }) + s.T().Logf("queryGetSpStoragePriceByTimeResp %s, err: %v", queryGetSpStoragePriceByTimeResp, err) + s.Require().NoError(err) + + readPrice := queryGetSpStoragePriceByTimeResp.GlobalSpStorePrice.ReadPrice + totalUserRate := readPrice.MulInt(sdkmath.NewIntFromUint64(bucketChargedReadQuota)).TruncateInt() + taxRateParam := params.VersionedParams.ValidatorTaxRate + taxStreamRate := taxRateParam.MulInt(totalUserRate).TruncateInt() + expectedRate := totalUserRate.Add(taxStreamRate) + paymentAccountBNBNeeded := expectedRate.Mul(sdkmath.NewIntFromUint64(reserveTime)) + + // create payment account and deposit + msgCreatePaymentAccount := &paymenttypes.MsgCreatePaymentAccount{ + Creator: user.GetAddr().String(), + } + _ = s.SendTxBlock(user, msgCreatePaymentAccount) + paymentAccountsReq := &paymenttypes.QueryPaymentAccountsByOwnerRequest{Owner: user.GetAddr().String()} + paymentAccounts, err := s.Client.PaymentQueryClient.PaymentAccountsByOwner(ctx, paymentAccountsReq) + s.Require().NoError(err) + s.T().Logf("paymentAccounts %s", core.YamlString(paymentAccounts)) + paymentAddr := paymentAccounts.PaymentAccounts[0] + s.Require().Lenf(paymentAccounts.PaymentAccounts, 1, "paymentAccounts %s", core.YamlString(paymentAccounts)) + msgDeposit := &paymenttypes.MsgDeposit{ + Creator: user.GetAddr().String(), + To: paymentAddr, + Amount: paymentAccountBNBNeeded, + } + _ = s.SendTxBlock(user, msgDeposit) + + paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{}) + s.T().Logf("paymentParams %s, err: %v", paymentParams, err) + s.Require().NoError(err) + + bucketName := "ch" + storagetestutils.GenRandomBucketName() + msgCreateBucket := storagetypes.NewMsgCreateBucket( + user.GetAddr(), bucketName, storagetypes.VISIBILITY_TYPE_PRIVATE, primarySP.OperatorKey.GetAddr(), + sdk.MustAccAddressFromHex(paymentAddr), math.MaxUint, nil, bucketChargedReadQuota) + msgCreateBucket.PrimarySpApproval.GlobalVirtualGroupFamilyId = gvg.FamilyId + msgCreateBucket.PrimarySpApproval.Sig, err = primarySP.ApprovalKey.Sign(msgCreateBucket.GetApprovalBytes()) + s.Require().NoError(err) + s.SendTxBlock(user, msgCreateBucket) + + queryHeadBucketRequest := storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + } + _, err = s.Client.HeadBucket(context.Background(), &queryHeadBucketRequest) + s.Require().NoError(err) + bucketInfo, err := s.Client.HeadBucket(context.Background(), &storagetypes.QueryHeadBucketRequest{ + BucketName: bucketName, + }) + s.Require().NoError(err) + + // wait until settle time + paymentAccountStreamRecord := s.getStreamRecord(paymentAddr) + retryCount := 0 + for { + latestBlock, err := s.TmClient.TmClient.Block(ctx, nil) + s.Require().NoError(err) + currentTimestamp := latestBlock.Block.Time.Unix() + s.T().Logf("currentTimestamp %d, userStreamRecord.SettleTimestamp %d", currentTimestamp, paymentAccountStreamRecord.SettleTimestamp) + if currentTimestamp > paymentAccountStreamRecord.SettleTimestamp { + break + } + time.Sleep(time.Second) + retryCount++ + if retryCount > 60 { + s.T().Fatalf("wait for settle time timeout") + } + } + // check auto settle + paymentAccountStreamRecordAfterAutoSettle := s.getStreamRecord(paymentAddr) + s.T().Logf("paymentAccountStreamRecordAfterAutoSettle %s", core.YamlString(paymentAccountStreamRecordAfterAutoSettle)) + s.Require().NotEqual(paymentAccountStreamRecordAfterAutoSettle.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) + + dstPrimarySP := s.CreateNewStorageProvider() + s.SetSPPrice(dstPrimarySP, "2", "1.45") + _, secondarySPIDs := s.GetSecondarySP(dstPrimarySP, primarySP) + gvgID, _ := s.BaseSuite.CreateGlobalVirtualGroup(dstPrimarySP, 0, secondarySPIDs, 1) + gvgResp, err := s.Client.VirtualGroupQueryClient.GlobalVirtualGroup(context.Background(), &virtualgrouptypes.QueryGlobalVirtualGroupRequest{ + GlobalVirtualGroupId: gvgID, + }) + s.Require().NoError(err) + dstGVG := gvgResp.GlobalVirtualGroup + s.Require().True(found) + + queryFamilyResponse, err = s.Client.GlobalVirtualGroupFamily(ctx, &virtualgrouptypes.QueryGlobalVirtualGroupFamilyRequest{ + FamilyId: dstGVG.FamilyId, + }) + s.Require().NoError(err) + family := queryFamilyResponse.GlobalVirtualGroupFamily + streamAddresses := []string{ + paymentAddr, + family.VirtualPaymentAddress, + dstGVG.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + fundAddress := primarySP.FundingKey.GetAddr() + streamRecordsBefore := s.getStreamRecords(streamAddresses) + + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: fundAddress.String()} + fundBalanceBefore, err := s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + + // MigrateBucket + msgMigrateBucket, msgCompleteMigrateBucket := s.NewMigrateBucket(primarySP, dstPrimarySP, user, bucketName, gvg.FamilyId, dstGVG.FamilyId, bucketInfo.BucketInfo.Id) + s.SendTxBlock(user, msgMigrateBucket) + s.Require().NoError(err) + + // complete MigrateBucket + s.SendTxBlock(dstPrimarySP.OperatorKey, msgCompleteMigrateBucket) + streamRecordsAfter := s.getStreamRecords(streamAddresses) + fundBalanceAfter, err := s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest) + s.Require().NoError(err) + s.T().Logf("fundBalanceBefore: %v, fundBalanceAfter: %v, diff: %v", fundBalanceBefore, fundBalanceAfter, fundBalanceAfter.Balance.Amount.Sub(fundBalanceBefore.Balance.Amount)) + s.Require().True(fundBalanceAfter.Balance.Amount.Sub(fundBalanceBefore.Balance.Amount).GT(sdkmath.NewInt(0)), "migrate sp fund address need settle") + gvgFamilyRate, taxRate, userTotalRate := s.calculateReadRates(dstPrimarySP, bucketName) + s.T().Logf("gvgFamilyRate: %v, taxRate: %v, userTotalRate: %v", gvgFamilyRate, taxRate, userTotalRate) + s.T().Logf("NetflowRate: %v, userTotalRate: %v, actual taxRate diff: %v, expect taxRate diff: %v", streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Neg(), streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + + s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.User.LockBalance, sdkmath.ZeroInt()) + s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate) + // tax rate diff + s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate) + s.Require().Equal(streamRecordsAfter.User.FrozenNetflowRate.Neg(), userTotalRate.Abs()) + + // force delete bucket + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(dstPrimarySP.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(dstPrimarySP.GcKey, msgDiscontinueBucket) + deleteAt := filterDiscontinueBucketEventFromTx(txRes).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, deleteAt) + + if blockTime > deleteAt { + break + } + } + + _, err = s.Client.HeadBucket(ctx, &storagetypes.QueryHeadBucketRequest{BucketName: bucketName}) + s.Require().ErrorContains(err, "No such bucket") +} + func (s *PaymentTestSuite) GetSecondarySP(sps ...*core.StorageProvider) ([]*core.StorageProvider, []uint32) { var secondarySPs []*core.StorageProvider var secondarySPIDs []uint32 @@ -2160,11 +2473,9 @@ func (s *PaymentTestSuite) reduceBNBBalance(user, to keys.KeyManager, leftBalanc s.T().Logf("balance: %v", queryBalanceResponse.Balance.Amount) } -func (s *PaymentTestSuite) transferBNB(user, to keys.KeyManager, amount sdkmath.Int) { - - msgSend := banktypes.NewMsgSend(user.GetAddr(), to.GetAddr(), sdk.NewCoins( +func (s *PaymentTestSuite) transferBNB(from, to keys.KeyManager, amount sdkmath.Int) { + msgSend := banktypes.NewMsgSend(from.GetAddr(), to.GetAddr(), sdk.NewCoins( sdk.NewCoin(s.Config.Denom, amount), )) - s.SendTxBlock(user, msgSend) - + s.SendTxBlock(from, msgSend) } diff --git a/e2e/tests/storage_test.go b/e2e/tests/storage_test.go index ce885ebc1..c340d1594 100644 --- a/e2e/tests/storage_test.go +++ b/e2e/tests/storage_test.go @@ -11,8 +11,6 @@ import ( "testing" "time" - sptypes "github.com/bnb-chain/greenfield/x/sp/types" - sdkmath "cosmossdk.io/math" ctypes "github.com/cometbft/cometbft/rpc/core/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -29,6 +27,7 @@ import ( "github.com/bnb-chain/greenfield/sdk/keys" "github.com/bnb-chain/greenfield/sdk/types" storageutils "github.com/bnb-chain/greenfield/testutil/storage" + sptypes "github.com/bnb-chain/greenfield/x/sp/types" storagetypes "github.com/bnb-chain/greenfield/x/storage/types" types2 "github.com/bnb-chain/greenfield/x/virtualgroup/types" ) diff --git a/proto/greenfield/sp/params.proto b/proto/greenfield/sp/params.proto index 2d62ae111..491492011 100644 --- a/proto/greenfield/sp/params.proto +++ b/proto/greenfield/sp/params.proto @@ -31,4 +31,8 @@ message Params { int64 maintenance_duration_quota = 5 [(gogoproto.moretags) = "yaml:\"maintenance_duration_quota\""]; // the number of blocks to be wait for sp to be in maintenance mode again if already requested int64 num_of_lockup_blocks_for_maintenance = 6 [(gogoproto.moretags) = "yaml:\"num_of_lockup_blocks_for_maintenance\""]; + // the time interval to update global storage price + uint64 update_global_price_interval = 7 [(gogoproto.moretags) = "yaml:\"update_global_price_interval\""]; + // the max times allowed to update price during an interval + uint32 max_update_price_times = 8 [(gogoproto.moretags) = "yaml:\"max_update_price_times\""]; } diff --git a/swagger/static/swagger.yaml b/swagger/static/swagger.yaml index 301da9331..c6aa45c83 100644 --- a/swagger/static/swagger.yaml +++ b/swagger/static/swagger.yaml @@ -1551,79 +1551,19 @@ paths: type: boolean tags: - Query - /greenfield/sp/get_secondary_sp_store_price_by_time/{timestamp}: + /greenfield/sp/global_sp_store_price_by_time/{timestamp}: get: - summary: get secondary store price by time - operationId: QueryGetSecondarySpStorePriceByTime + summary: get global store price by time + operationId: QueryGlobalSpStorePriceByTime responses: '200': description: A successful response. schema: type: object properties: - secondary_sp_store_price: + global_sp_store_price: type: object properties: - update_time_sec: - type: string - format: int64 - title: update time, unix timestamp in seconds - store_price: - type: string - title: store price, in bnb wei per charge byte - title: >- - global secondary sp store price, the price for all secondary - sps - default: - description: An unexpected error response. - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: - type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - value: - type: string - format: byte - parameters: - - name: timestamp - description: >- - unix timestamp in seconds. If it's 0, it will return the latest - price. - in: path - required: true - type: string - format: int64 - tags: - - Query - /greenfield/sp/get_sp_storage_price_by_time/{sp_addr}/{timestamp}: - get: - summary: get storage price of specific sp and time - operationId: QueryGetSpStoragePriceByTime - responses: - '200': - description: A successful response. - schema: - type: object - properties: - sp_storage_price: - type: object - properties: - sp_id: - type: integer - format: int64 - title: sp id update_time_sec: type: string format: int64 @@ -1631,14 +1571,13 @@ paths: read_price: type: string title: read price, in bnb wei per charge byte - free_read_quota: + primary_store_price: type: string - format: uint64 - title: free read quota, in byte - store_price: + title: primary store price, in bnb wei per charge byte + secondary_store_price: type: string - title: store price, in bnb wei per charge byte - title: storage price of a specific sp + title: secondary store price, in bnb wei per charge byte + title: global sp store price, the price for all sps default: description: An unexpected error response. schema: @@ -1662,11 +1601,6 @@ paths: type: string format: byte parameters: - - name: sp_addr - description: operator address of sp - in: path - required: true - type: string - name: timestamp description: >- unix timestamp in seconds. If it's 0, it will return the latest @@ -1722,6 +1656,14 @@ paths: title: >- the number of blocks to be wait for sp to be in maintenance mode again if already requested + update_global_price_interval: + type: string + format: uint64 + title: the time interval to update global storage price + max_update_price_times: + type: integer + format: int64 + title: the max times allowed to update price during an interval description: >- QueryParamsResponse is response type for the Query/Params RPC method. @@ -1749,6 +1691,68 @@ paths: format: byte tags: - Query + /greenfield/sp/sp_storage_price/{sp_addr}: + get: + summary: get the latest storage price of specific sp + operationId: QuerySpStoragePrice + responses: + '200': + description: A successful response. + schema: + type: object + properties: + sp_storage_price: + type: object + properties: + sp_id: + type: integer + format: int64 + title: sp id + update_time_sec: + type: string + format: int64 + title: update time, unix timestamp in seconds + read_price: + type: string + title: read price, in bnb wei per charge byte + free_read_quota: + type: string + format: uint64 + title: free read quota, in byte + store_price: + type: string + title: store price, in bnb wei per charge byte + title: storage price of a specific sp + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: sp_addr + description: operator address of sp + in: path + required: true + type: string + tags: + - Query /greenfield/sp/storage_provider_by_operator_address: get: summary: Queries a StorageProvider by specify operator address. @@ -32703,6 +32707,23 @@ definitions: type: string description: details define other optional details. description: Description defines a storage provider description. + greenfield.sp.GlobalSpStorePrice: + type: object + properties: + update_time_sec: + type: string + format: int64 + title: update time, unix timestamp in seconds + read_price: + type: string + title: read price, in bnb wei per charge byte + primary_store_price: + type: string + title: primary store price, in bnb wei per charge byte + secondary_store_price: + type: string + title: secondary store price, in bnb wei per charge byte + title: global sp store price, the price for all sps greenfield.sp.MaintenanceRecord: type: object properties: @@ -32755,31 +32776,21 @@ definitions: title: >- the number of blocks to be wait for sp to be in maintenance mode again if already requested + update_global_price_interval: + type: string + format: uint64 + title: the time interval to update global storage price + max_update_price_times: + type: integer + format: int64 + title: the max times allowed to update price during an interval description: Params defines the parameters for the module. - greenfield.sp.QueryGetSecondarySpStorePriceByTimeResponse: + greenfield.sp.QueryGlobalSpStorePriceByTimeResponse: type: object properties: - secondary_sp_store_price: + global_sp_store_price: type: object properties: - update_time_sec: - type: string - format: int64 - title: update time, unix timestamp in seconds - store_price: - type: string - title: store price, in bnb wei per charge byte - title: global secondary sp store price, the price for all secondary sps - greenfield.sp.QueryGetSpStoragePriceByTimeResponse: - type: object - properties: - sp_storage_price: - type: object - properties: - sp_id: - type: integer - format: int64 - title: sp id update_time_sec: type: string format: int64 @@ -32787,14 +32798,13 @@ definitions: read_price: type: string title: read price, in bnb wei per charge byte - free_read_quota: + primary_store_price: type: string - format: uint64 - title: free read quota, in byte - store_price: + title: primary store price, in bnb wei per charge byte + secondary_store_price: type: string - title: store price, in bnb wei per charge byte - title: storage price of a specific sp + title: secondary store price, in bnb wei per charge byte + title: global sp store price, the price for all sps greenfield.sp.QueryParamsResponse: type: object properties: @@ -32831,7 +32841,40 @@ definitions: title: >- the number of blocks to be wait for sp to be in maintenance mode again if already requested + update_global_price_interval: + type: string + format: uint64 + title: the time interval to update global storage price + max_update_price_times: + type: integer + format: int64 + title: the max times allowed to update price during an interval description: QueryParamsResponse is response type for the Query/Params RPC method. + greenfield.sp.QuerySpStoragePriceResponse: + type: object + properties: + sp_storage_price: + type: object + properties: + sp_id: + type: integer + format: int64 + title: sp id + update_time_sec: + type: string + format: int64 + title: update time, unix timestamp in seconds + read_price: + type: string + title: read price, in bnb wei per charge byte + free_read_quota: + type: string + format: uint64 + title: free read quota, in byte + store_price: + type: string + title: store price, in bnb wei per charge byte + title: storage price of a specific sp greenfield.sp.QueryStorageProviderByOperatorAddressResponse: type: object properties: @@ -33160,17 +33203,6 @@ definitions: PageRequest.count_total was set, its value is undefined otherwise - greenfield.sp.SecondarySpStorePrice: - type: object - properties: - update_time_sec: - type: string - format: int64 - title: update time, unix timestamp in seconds - store_price: - type: string - title: store price, in bnb wei per charge byte - title: global secondary sp store price, the price for all secondary sps greenfield.sp.SpStoragePrice: type: object properties: diff --git a/x/bridge/client/cli/tx_test.go b/x/bridge/client/cli/tx_test.go index 3f04f8dfb..09124a371 100644 --- a/x/bridge/client/cli/tx_test.go +++ b/x/bridge/client/cli/tx_test.go @@ -9,7 +9,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" @@ -19,8 +21,6 @@ import ( "github.com/bnb-chain/greenfield/sdk/client/test" "github.com/bnb-chain/greenfield/testutil/sample" "github.com/bnb-chain/greenfield/x/bridge/client/cli" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/testutil" ) type CLITestSuite struct { diff --git a/x/challenge/client/cli/query_test.go b/x/challenge/client/cli/query_test.go index cfb109862..1ac6147f3 100644 --- a/x/challenge/client/cli/query_test.go +++ b/x/challenge/client/cli/query_test.go @@ -3,12 +3,12 @@ package cli_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/client/flags" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/gogoproto/proto" "github.com/bnb-chain/greenfield/x/challenge/client/cli" "github.com/bnb-chain/greenfield/x/challenge/types" - "github.com/cosmos/cosmos-sdk/client/flags" ) func (s *CLITestSuite) TestQueryCmd() { diff --git a/x/payment/client/cli/query_test.go b/x/payment/client/cli/query_test.go index 7d791d968..a02d24818 100644 --- a/x/payment/client/cli/query_test.go +++ b/x/payment/client/cli/query_test.go @@ -3,13 +3,13 @@ package cli_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/client/flags" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/gogoproto/proto" "github.com/bnb-chain/greenfield/testutil/sample" "github.com/bnb-chain/greenfield/x/payment/client/cli" "github.com/bnb-chain/greenfield/x/payment/types" - "github.com/cosmos/cosmos-sdk/client/flags" ) func (s *CLITestSuite) TestQueryCmd() { diff --git a/x/permission/client/cli/query_test.go b/x/permission/client/cli/query_test.go index 44d63f5c6..5ffb5532b 100644 --- a/x/permission/client/cli/query_test.go +++ b/x/permission/client/cli/query_test.go @@ -3,12 +3,12 @@ package cli_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/client/flags" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/gogoproto/proto" "github.com/bnb-chain/greenfield/x/payment/client/cli" "github.com/bnb-chain/greenfield/x/payment/types" - "github.com/cosmos/cosmos-sdk/client/flags" ) func (s *CLITestSuite) TestQueryCmd() { diff --git a/x/sp/abci.go b/x/sp/abci.go index 0dbf50802..a7cda816d 100644 --- a/x/sp/abci.go +++ b/x/sp/abci.go @@ -1,13 +1,25 @@ package sp import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/bnb-chain/greenfield/x/sp/keeper" "github.com/bnb-chain/greenfield/x/sp/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) func EndBlocker(ctx sdk.Context, k keeper.Keeper) { if ctx.BlockHeight()%types.MaintenanceRecordsGCFrequencyInBlocks == 0 { k.ForceUpdateMaintenanceRecords(ctx) } + + blockTime := ctx.BlockTime().Unix() + params := k.GetParams(ctx) + price, err := k.GetGlobalSpStorePriceByTime(ctx, blockTime+1) + if err != nil || blockTime-price.UpdateTimeSec > int64(params.UpdateGlobalPriceInterval) { // no global price yet or need to update + err = k.UpdateGlobalSpStorePrice(ctx) + if err != nil { + ctx.Logger().Error("fail to update global sp store price", "err", err) + } + k.ClearSpUpdatePriceTimes(ctx) + } } diff --git a/x/sp/client/cli/query_test.go b/x/sp/client/cli/query_test.go index f7dbf1a80..7c59b700b 100644 --- a/x/sp/client/cli/query_test.go +++ b/x/sp/client/cli/query_test.go @@ -3,13 +3,13 @@ package cli_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/client/flags" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/gogoproto/proto" "github.com/bnb-chain/greenfield/testutil/sample" "github.com/bnb-chain/greenfield/x/sp/client/cli" "github.com/bnb-chain/greenfield/x/sp/types" - "github.com/cosmos/cosmos-sdk/client/flags" ) func (s *CLITestSuite) TestQueryCmd() { diff --git a/x/sp/keeper/msg_server.go b/x/sp/keeper/msg_server.go index ce6096ee1..edf9e3a67 100644 --- a/x/sp/keeper/msg_server.go +++ b/x/sp/keeper/msg_server.go @@ -152,10 +152,7 @@ func (k msgServer) CreateStorageProvider(goCtx context.Context, msg *types.MsgCr FreeReadQuota: msg.FreeReadQuota, } k.SetSpStoragePrice(ctx, spStoragePrice) - err = k.UpdateGlobalSpStorePrice(ctx) - if err != nil { - return nil, err - } + k.SetSpUpdatePriceTimes(ctx, sp.Id, k.GetSpUpdatePriceTimes(ctx, sp.Id)+1) if err = ctx.EventManager().EmitTypedEvents(&types.EventCreateStorageProvider{ SpId: sp.Id, @@ -318,6 +315,12 @@ func (k msgServer) UpdateSpStoragePrice(goCtx context.Context, msg *types.MsgUpd return nil, types.ErrStorageProviderNotInService } + updateTimes := k.GetSpUpdatePriceTimes(ctx, sp.Id) + params := k.GetParams(ctx) + if updateTimes+1 >= params.MaxUpdatePriceTimes { + return nil, types.ErrStorageProviderPriceUpdateNotAllow + } + current := ctx.BlockTime().Unix() spStorePrice := types.SpStoragePrice{ UpdateTimeSec: current, @@ -327,10 +330,8 @@ func (k msgServer) UpdateSpStoragePrice(goCtx context.Context, msg *types.MsgUpd FreeReadQuota: msg.FreeReadQuota, } k.SetSpStoragePrice(ctx, spStorePrice) - err := k.UpdateGlobalSpStorePrice(ctx) - if err != nil { - return nil, errors.Wrapf(err, "update secondary sp store price failed") - } + k.SetSpUpdatePriceTimes(ctx, sp.Id, updateTimes+1) + return &types.MsgUpdateSpStoragePriceResponse{}, nil } diff --git a/x/sp/keeper/sp_status.go b/x/sp/keeper/sp_status.go index acdf83560..0a7359a6a 100644 --- a/x/sp/keeper/sp_status.go +++ b/x/sp/keeper/sp_status.go @@ -2,9 +2,10 @@ package keeper import ( "cosmossdk.io/errors" - "github.com/bnb-chain/greenfield/x/sp/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/bnb-chain/greenfield/x/sp/types" ) func (k Keeper) UpdateToInMaintenance(ctx sdk.Context, sp *types.StorageProvider, requestDuration int64) error { diff --git a/x/sp/keeper/sp_storage_price.go b/x/sp/keeper/sp_storage_price.go index c9f0ac3f9..b51473868 100644 --- a/x/sp/keeper/sp_storage_price.go +++ b/x/sp/keeper/sp_storage_price.go @@ -1,6 +1,7 @@ package keeper import ( + "encoding/binary" "fmt" "sort" @@ -145,3 +146,35 @@ func (k Keeper) GetGlobalSpStorePriceByTime(ctx sdk.Context, time int64) (val ty val.UpdateTimeSec = updateTimeSec return val, nil } + +func (k Keeper) SetSpUpdatePriceTimes(ctx sdk.Context, spId uint32, times uint32) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.SpStoragePriceUpdateTimesKeyPrefix) + idBz := make([]byte, 4) + binary.BigEndian.PutUint32(idBz, spId) + timesBz := make([]byte, 4) + binary.BigEndian.PutUint32(timesBz, times) + store.Set(idBz, timesBz) +} + +func (k Keeper) GetSpUpdatePriceTimes(ctx sdk.Context, spId uint32) uint32 { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.SpStoragePriceUpdateTimesKeyPrefix) + idBz := make([]byte, 4) + binary.BigEndian.PutUint32(idBz, spId) + timesBz := store.Get(idBz) + if timesBz == nil { + return 0 + } + times := binary.BigEndian.Uint32(timesBz) + return times +} + +func (k Keeper) ClearSpUpdatePriceTimes(ctx sdk.Context) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.SpStoragePriceUpdateTimesKeyPrefix) + + iterator := storetypes.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + store.Delete(iterator.Key()) + } +} diff --git a/x/sp/types/errors.go b/x/sp/types/errors.go index 1824ca068..ed55ff5c4 100644 --- a/x/sp/types/errors.go +++ b/x/sp/types/errors.go @@ -23,6 +23,7 @@ var ( ErrStorageProviderBlsKeyExists = errors.Register(ModuleName, 15, "StorageProvider already exist for this bls pubkey; must use new bls pubkey") ErrStorageProviderStatusUpdateNotAllow = errors.Register(ModuleName, 16, "StorageProvider status is not allow to change") ErrStorageProviderMaintenanceAddrExists = errors.Register(ModuleName, 17, "StorageProvider already exist for this maintenance address; must use new StorageProvider maintenance address.") + ErrStorageProviderPriceUpdateNotAllow = errors.Register(ModuleName, 18, "StorageProvider cannot update price due to frequency limited.") ErrSignerNotGovModule = errors.Register(ModuleName, 40, "signer is not gov module account") ErrSignerEmpty = errors.Register(ModuleName, 41, "signer is empty") diff --git a/x/sp/types/keys.go b/x/sp/types/keys.go index e9ca69c2e..d0d3d464e 100644 --- a/x/sp/types/keys.go +++ b/x/sp/types/keys.go @@ -24,16 +24,17 @@ const ( var ( ParamsKey = []byte{0x01} - StorageProviderKey = []byte{0x21} // prefix for each key to a storage provider - StorageProviderByOperatorAddrKey = []byte{0x23} // prefix for each key to a storage provider index, by operator address - StorageProviderByFundingAddrKey = []byte{0x24} // prefix for each key to a storage provider index, by funding address - StorageProviderBySealAddrKey = []byte{0x25} // prefix for each key to a storage provider index, by seal address - StorageProviderByApprovalAddrKey = []byte{0x26} // prefix for each key to a storage provider index, by approval address - StorageProviderByGcAddrKey = []byte{0x27} // prefix for each key to a storage provider index, by gc address - SpStoragePriceKeyPrefix = []byte{0x28} - GlobalSpStorePriceKeyPrefix = []byte{0x29} - StorageProviderByBlsPubKeyKey = []byte{0x30} // prefix for each key to a storage provider index, by bls pub key - StorageProviderSequenceKey = []byte{0x31} + StorageProviderKey = []byte{0x21} // prefix for each key to a storage provider + StorageProviderByOperatorAddrKey = []byte{0x23} // prefix for each key to a storage provider index, by operator address + StorageProviderByFundingAddrKey = []byte{0x24} // prefix for each key to a storage provider index, by funding address + StorageProviderBySealAddrKey = []byte{0x25} // prefix for each key to a storage provider index, by seal address + StorageProviderByApprovalAddrKey = []byte{0x26} // prefix for each key to a storage provider index, by approval address + StorageProviderByGcAddrKey = []byte{0x27} // prefix for each key to a storage provider index, by gc address + SpStoragePriceKeyPrefix = []byte{0x28} + GlobalSpStorePriceKeyPrefix = []byte{0x29} + StorageProviderByBlsPubKeyKey = []byte{0x30} // prefix for each key to a storage provider index, by bls pub key + StorageProviderSequenceKey = []byte{0x31} + SpStoragePriceUpdateTimesKeyPrefix = []byte{0x32} StorageProviderMaintenanceRecordPrefix = []byte{0x41} ) @@ -109,9 +110,7 @@ func ParseSpStoragePriceKey(key []byte) (spId uint32) { return } -func GlobalSpStorePriceKey( - timestamp int64, -) []byte { +func GlobalSpStorePriceKey(timestamp int64) []byte { timeBytes := make([]byte, 8) binary.BigEndian.PutUint64(timeBytes, uint64(timestamp)) return timeBytes diff --git a/x/sp/types/params.go b/x/sp/types/params.go index d25650a30..bdf8ff2e9 100644 --- a/x/sp/types/params.go +++ b/x/sp/types/params.go @@ -22,6 +22,10 @@ const ( DefaultMaintenanceDurationQuota = 21600 // 6 hour // DefaultNumOfLockUpBlocksForMaintenance defines blocks difference which Sp update itself to Maintenance mode is allowed DefaultNumOfLockUpBlocksForMaintenance = 21600 + // DefaultUpdateGlobalPriceInterval defines the default time duration for updating global storage price + DefaultUpdateGlobalPriceInterval uint64 = 30 * 24 * 60 * 60 // 30 days + // DefaultMaxUpdatePriceTimes defines the max allowed times to update price for each sp in one interval + DefaultMaxUpdatePriceTimes uint32 = 3 ) var ( @@ -38,6 +42,8 @@ var ( KeyNumOfHistoricalBlocksForMaintenanceRecords = []byte("NumOfHistoricalBlocksForMaintenanceRecords") KeyMaintenanceDurationQuota = []byte("MaintenanceDurationQuota") KeyNumOfLockUpBlocksForMaintenance = []byte("NumOfLockUpBlocksForMaintenance") + KeyUpdateGlobalPriceInterval = []byte("UpdateGlobalPriceInterval") + KeyMaxUpdatePriceTimes = []byte("MaxUpdatePriceTimes") ) var _ paramtypes.ParamSet = (*Params)(nil) @@ -49,7 +55,8 @@ func ParamKeyTable() paramtypes.KeyTable { // NewParams creates a new Params instance func NewParams(depositDenom string, minDeposit math.Int, secondarySpStorePriceRatio sdk.Dec, - historicalBlocksForMaintenanceRecords, maintenanceDurationQuota, lockUpBlocksForMaintenance int64) Params { + historicalBlocksForMaintenanceRecords, maintenanceDurationQuota, lockUpBlocksForMaintenance int64, + updateGlobalPriceInterval uint64, maxUpdatePriceTimes uint32) Params { return Params{ DepositDenom: depositDenom, MinDeposit: minDeposit, @@ -57,13 +64,16 @@ func NewParams(depositDenom string, minDeposit math.Int, secondarySpStorePriceRa NumOfHistoricalBlocksForMaintenanceRecords: historicalBlocksForMaintenanceRecords, MaintenanceDurationQuota: maintenanceDurationQuota, NumOfLockupBlocksForMaintenance: lockUpBlocksForMaintenance, + UpdateGlobalPriceInterval: updateGlobalPriceInterval, + MaxUpdatePriceTimes: maxUpdatePriceTimes, } } // DefaultParams returns a default set of parameters func DefaultParams() Params { return NewParams(DefaultDepositDenom, DefaultMinDeposit, DefaultSecondarySpStorePriceRatio, - DefaultNumOfHistoricalBlocksForMaintenanceRecords, DefaultMaintenanceDurationQuota, DefaultNumOfLockUpBlocksForMaintenance) + DefaultNumOfHistoricalBlocksForMaintenanceRecords, DefaultMaintenanceDurationQuota, DefaultNumOfLockUpBlocksForMaintenance, + DefaultUpdateGlobalPriceInterval, DefaultMaxUpdatePriceTimes) } // ParamSetPairs get the params.ParamSet @@ -75,6 +85,8 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyNumOfHistoricalBlocksForMaintenanceRecords, &p.NumOfHistoricalBlocksForMaintenanceRecords, validateHistoricalBlocksForMaintenanceRecords), paramtypes.NewParamSetPair(KeyMaintenanceDurationQuota, &p.MaintenanceDurationQuota, validateMaintenanceDurationQuota), paramtypes.NewParamSetPair(KeyNumOfLockUpBlocksForMaintenance, &p.NumOfLockupBlocksForMaintenance, validateLockUpBlocksForMaintenance), + paramtypes.NewParamSetPair(KeyUpdateGlobalPriceInterval, &p.UpdateGlobalPriceInterval, validateUpdateGlobalPriceInterval), + paramtypes.NewParamSetPair(KeyMaxUpdatePriceTimes, &p.MaxUpdatePriceTimes, validateMaxUpdatePriceTimes), } } @@ -100,6 +112,13 @@ func (p Params) Validate() error { if err := validateLockUpBlocksForMaintenance(p.NumOfLockupBlocksForMaintenance); err != nil { return err } + if err := validateUpdateGlobalPriceInterval(p.UpdateGlobalPriceInterval); err != nil { + return err + } + if err := validateMaxUpdatePriceTimes(p.MaxUpdatePriceTimes); err != nil { + return err + } + return nil } @@ -175,6 +194,7 @@ func validateMaintenanceDurationQuota(i interface{}) error { } return nil } + func validateLockUpBlocksForMaintenance(i interface{}) error { v, ok := i.(int64) if !ok { @@ -185,3 +205,25 @@ func validateLockUpBlocksForMaintenance(i interface{}) error { } return nil } + +func validateUpdateGlobalPriceInterval(i interface{}) error { + v, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if v == 0 { + return errors.New("UpdateGlobalPriceInterval cannot be zero") + } + return nil +} + +func validateMaxUpdatePriceTimes(i interface{}) error { + v, ok := i.(uint32) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if v == 0 { + return errors.New("MaxUpdatePriceTimes cannot be zero") + } + return nil +} diff --git a/x/sp/types/params.pb.go b/x/sp/types/params.pb.go index eb8246bf7..409be5ac5 100644 --- a/x/sp/types/params.pb.go +++ b/x/sp/types/params.pb.go @@ -39,6 +39,10 @@ type Params struct { MaintenanceDurationQuota int64 `protobuf:"varint,5,opt,name=maintenance_duration_quota,json=maintenanceDurationQuota,proto3" json:"maintenance_duration_quota,omitempty" yaml:"maintenance_duration_quota"` // the number of blocks to be wait for sp to be in maintenance mode again if already requested NumOfLockupBlocksForMaintenance int64 `protobuf:"varint,6,opt,name=num_of_lockup_blocks_for_maintenance,json=numOfLockupBlocksForMaintenance,proto3" json:"num_of_lockup_blocks_for_maintenance,omitempty" yaml:"num_of_lockup_blocks_for_maintenance"` + // the time interval to update global storage price + UpdateGlobalPriceInterval uint64 `protobuf:"varint,7,opt,name=update_global_price_interval,json=updateGlobalPriceInterval,proto3" json:"update_global_price_interval,omitempty" yaml:"update_global_price_interval"` + // the max times allowed to update price during an interval + MaxUpdatePriceTimes uint32 `protobuf:"varint,8,opt,name=max_update_price_times,json=maxUpdatePriceTimes,proto3" json:"max_update_price_times,omitempty" yaml:"max_update_price_times"` } func (m *Params) Reset() { *m = Params{} } @@ -101,6 +105,20 @@ func (m *Params) GetNumOfLockupBlocksForMaintenance() int64 { return 0 } +func (m *Params) GetUpdateGlobalPriceInterval() uint64 { + if m != nil { + return m.UpdateGlobalPriceInterval + } + return 0 +} + +func (m *Params) GetMaxUpdatePriceTimes() uint32 { + if m != nil { + return m.MaxUpdatePriceTimes + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "greenfield.sp.Params") } @@ -108,37 +126,43 @@ func init() { func init() { proto.RegisterFile("greenfield/sp/params.proto", fileDescriptor_a5353d8e6e407d7e) } var fileDescriptor_a5353d8e6e407d7e = []byte{ - // 479 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x4d, 0x6b, 0xd4, 0x4e, - 0x1c, 0x4e, 0xfe, 0xfd, 0x77, 0xd1, 0xd1, 0x5e, 0x82, 0x87, 0x98, 0x43, 0x52, 0xe3, 0x0b, 0xa5, - 0xb2, 0x1b, 0xc1, 0x83, 0x50, 0x3d, 0x2d, 0x41, 0x2c, 0x28, 0xd6, 0xf4, 0x26, 0xc8, 0x30, 0x99, - 0xcc, 0xee, 0x0e, 0xdd, 0x79, 0x71, 0x66, 0x02, 0xee, 0x45, 0xfc, 0x08, 0x1e, 0x3d, 0x56, 0x3f, - 0x83, 0x1f, 0xa2, 0xc7, 0xe2, 0x49, 0x3c, 0x04, 0xd9, 0xbd, 0x78, 0xde, 0x4f, 0x20, 0x33, 0x09, - 0x6d, 0x04, 0x2b, 0xf4, 0x94, 0xe4, 0xf7, 0x3c, 0xf3, 0xbc, 0x64, 0x66, 0x40, 0x34, 0x55, 0x84, - 0xf0, 0x09, 0x25, 0xf3, 0x2a, 0xd3, 0x32, 0x93, 0x48, 0x21, 0xa6, 0x47, 0x52, 0x09, 0x23, 0x82, - 0xad, 0x73, 0x6c, 0xa4, 0x65, 0x74, 0x13, 0x0b, 0xcd, 0x84, 0x86, 0x0e, 0xcc, 0xda, 0x8f, 0x96, - 0x19, 0xdd, 0x98, 0x8a, 0xa9, 0x68, 0xe7, 0xf6, 0xad, 0x9d, 0xa6, 0x5f, 0x36, 0xc1, 0xe0, 0xc0, - 0x09, 0x06, 0xb7, 0xc1, 0x56, 0x45, 0xa4, 0xd0, 0xd4, 0xc0, 0x8a, 0x70, 0xc1, 0x42, 0x7f, 0xdb, - 0xdf, 0xb9, 0x5a, 0x5c, 0xef, 0x86, 0xb9, 0x9d, 0x05, 0x6f, 0xc0, 0x35, 0x46, 0x39, 0xec, 0x66, - 0xe1, 0x7f, 0x96, 0x32, 0x7e, 0x72, 0xd2, 0x24, 0xde, 0x8f, 0x26, 0xb9, 0x37, 0xa5, 0x66, 0x56, - 0x97, 0x23, 0x2c, 0x58, 0xe7, 0xdd, 0x3d, 0x86, 0xba, 0x3a, 0xca, 0xcc, 0x42, 0x12, 0x3d, 0xda, - 0xe7, 0xe6, 0xdb, 0xd7, 0x21, 0xe8, 0xa2, 0xed, 0x73, 0x53, 0x00, 0x46, 0x79, 0xde, 0xea, 0x05, - 0x1f, 0x7c, 0x10, 0x6b, 0x82, 0x05, 0xaf, 0x90, 0x5a, 0x40, 0x2d, 0xa1, 0x36, 0x42, 0x11, 0x28, - 0x15, 0xc5, 0x04, 0x2a, 0x64, 0xa8, 0x08, 0x37, 0x2e, 0x6d, 0x99, 0x13, 0xdc, 0xb3, 0xcc, 0x09, - 0x2e, 0xa2, 0x33, 0x8f, 0x43, 0x79, 0x68, 0x1d, 0x0e, 0xac, 0x41, 0x61, 0xf5, 0x83, 0xcf, 0x3e, - 0x78, 0xc0, 0x6b, 0x06, 0xc5, 0x04, 0xce, 0xa8, 0xb5, 0xa7, 0x18, 0xcd, 0x61, 0x39, 0x17, 0xf8, - 0x48, 0xc3, 0x89, 0x50, 0x90, 0x21, 0xca, 0x0d, 0xe1, 0x88, 0xdb, 0x48, 0x04, 0x0b, 0x55, 0xe9, - 0xf0, 0xff, 0x6d, 0x7f, 0x67, 0x63, 0xfc, 0x78, 0xdd, 0x24, 0x8f, 0x16, 0x88, 0xcd, 0xf7, 0xd2, - 0xcb, 0x2a, 0xa4, 0xc5, 0x2e, 0xaf, 0xd9, 0xcb, 0xc9, 0xb3, 0xb3, 0x05, 0x63, 0xc7, 0x7f, 0x2a, - 0xd4, 0x8b, 0x73, 0x76, 0xd1, 0x92, 0x03, 0x0c, 0xa2, 0xbe, 0x46, 0x55, 0xbb, 0x5f, 0xc3, 0xe1, - 0xdb, 0x5a, 0x18, 0x14, 0x6e, 0xba, 0x30, 0x77, 0xd7, 0x4d, 0x72, 0xab, 0x0d, 0x73, 0x31, 0x37, - 0x2d, 0xc2, 0x1e, 0x98, 0x77, 0xd8, 0x2b, 0x0b, 0x05, 0xef, 0xc1, 0x9d, 0xae, 0x85, 0x4d, 0x52, - 0xcb, 0x0b, 0x1a, 0x84, 0x03, 0x67, 0x97, 0xad, 0x9b, 0xe4, 0xfe, 0x1f, 0xdd, 0xff, 0xb9, 0x2a, - 0x2d, 0x12, 0xd7, 0xf7, 0xb9, 0x23, 0xfd, 0xad, 0xeb, 0xde, 0x95, 0x4f, 0xc7, 0x89, 0xf7, 0xeb, - 0x38, 0xf1, 0xc7, 0xf9, 0xc9, 0x32, 0xf6, 0x4f, 0x97, 0xb1, 0xff, 0x73, 0x19, 0xfb, 0x1f, 0x57, - 0xb1, 0x77, 0xba, 0x8a, 0xbd, 0xef, 0xab, 0xd8, 0x7b, 0xbd, 0xdb, 0xdb, 0xfe, 0x92, 0x97, 0x43, - 0x3c, 0x43, 0x94, 0x67, 0xbd, 0xfb, 0xf2, 0xce, 0xde, 0x18, 0x77, 0x0c, 0xca, 0x81, 0x3b, 0xf1, - 0x0f, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x4d, 0x34, 0x14, 0x4a, 0x4f, 0x03, 0x00, 0x00, + // 569 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x4f, 0x6f, 0xd3, 0x30, + 0x1c, 0x6d, 0xd8, 0x28, 0xc3, 0xb0, 0x4b, 0x40, 0x28, 0xab, 0x20, 0xe9, 0x32, 0xfe, 0x54, 0x43, + 0x6d, 0x90, 0x38, 0x20, 0x0d, 0x4e, 0x51, 0x04, 0x54, 0x02, 0x31, 0x32, 0xe0, 0x80, 0x84, 0x2c, + 0x27, 0x71, 0x5b, 0x6b, 0xb1, 0x1d, 0x62, 0x07, 0xb5, 0x17, 0xc4, 0x47, 0xe0, 0xc8, 0x71, 0x7c, + 0x07, 0x3e, 0xc4, 0x8e, 0x13, 0x27, 0xc4, 0x21, 0x42, 0x2d, 0x07, 0xce, 0xfd, 0x04, 0xc8, 0x4e, + 0xd8, 0x8a, 0xb4, 0x4d, 0xda, 0x29, 0xc9, 0x7b, 0xef, 0xf7, 0xde, 0xef, 0xe7, 0xf8, 0x07, 0x5a, + 0xc3, 0x1c, 0x63, 0x36, 0x20, 0x38, 0x4d, 0x3c, 0x91, 0x79, 0x19, 0xca, 0x11, 0x15, 0xbd, 0x2c, + 0xe7, 0x92, 0x9b, 0xab, 0x47, 0x5c, 0x4f, 0x64, 0xad, 0xb5, 0x98, 0x0b, 0xca, 0x05, 0xd4, 0xa4, + 0x57, 0x7d, 0x54, 0xca, 0xd6, 0xd5, 0x21, 0x1f, 0xf2, 0x0a, 0x57, 0x6f, 0x15, 0xea, 0xfe, 0x6e, + 0x82, 0xe6, 0xb6, 0x36, 0x34, 0x37, 0xc0, 0x6a, 0x82, 0x33, 0x2e, 0x88, 0x84, 0x09, 0x66, 0x9c, + 0x5a, 0x46, 0xdb, 0xe8, 0x5c, 0x0c, 0x2f, 0xd7, 0x60, 0xa0, 0x30, 0xf3, 0x1d, 0xb8, 0x44, 0x09, + 0x83, 0x35, 0x66, 0x9d, 0x53, 0x12, 0xff, 0xd1, 0x7e, 0xe9, 0x34, 0x7e, 0x96, 0xce, 0xed, 0x21, + 0x91, 0xa3, 0x22, 0xea, 0xc5, 0x9c, 0xd6, 0xd9, 0xf5, 0xa3, 0x2b, 0x92, 0x5d, 0x4f, 0x4e, 0x32, + 0x2c, 0x7a, 0x7d, 0x26, 0xbf, 0x7f, 0xeb, 0x82, 0xba, 0xb5, 0x3e, 0x93, 0x21, 0xa0, 0x84, 0x05, + 0x95, 0x9f, 0xf9, 0xc9, 0x00, 0xb6, 0xc0, 0x31, 0x67, 0x09, 0xca, 0x27, 0x50, 0x64, 0x50, 0x48, + 0x9e, 0x63, 0x98, 0xe5, 0x24, 0xc6, 0x30, 0x47, 0x92, 0x70, 0x6b, 0xe9, 0xcc, 0x91, 0x01, 0x8e, + 0x17, 0x22, 0x03, 0x1c, 0x87, 0xad, 0xc3, 0x8c, 0x9d, 0x6c, 0x47, 0x25, 0x6c, 0xab, 0x80, 0x50, + 0xf9, 0x9b, 0x5f, 0x0d, 0x70, 0x8f, 0x15, 0x14, 0xf2, 0x01, 0x1c, 0x11, 0x15, 0x4f, 0x62, 0x94, + 0xc2, 0x28, 0xe5, 0xf1, 0xae, 0x80, 0x03, 0x9e, 0x43, 0x8a, 0x08, 0x93, 0x98, 0x21, 0xa6, 0x5a, + 0xc2, 0x31, 0xcf, 0x13, 0x61, 0x2d, 0xb7, 0x8d, 0xce, 0x92, 0xff, 0x70, 0x5e, 0x3a, 0x0f, 0x26, + 0x88, 0xa6, 0x5b, 0xee, 0x59, 0x1d, 0xdc, 0x70, 0x93, 0x15, 0xf4, 0xc5, 0xe0, 0xe9, 0x61, 0x81, + 0xaf, 0xf5, 0x8f, 0x79, 0xfe, 0xfc, 0x48, 0x1d, 0x56, 0x62, 0x33, 0x06, 0xad, 0x45, 0x8f, 0xa4, + 0xd0, 0x47, 0xc3, 0xe0, 0xfb, 0x82, 0x4b, 0x64, 0x9d, 0xd7, 0xcd, 0xdc, 0x9a, 0x97, 0xce, 0x7a, + 0xd5, 0xcc, 0xc9, 0x5a, 0x37, 0xb4, 0x16, 0xc8, 0xa0, 0xe6, 0x5e, 0x2a, 0xca, 0xfc, 0x08, 0x6e, + 0xd6, 0x53, 0xa8, 0x4e, 0x8a, 0xec, 0x84, 0x09, 0xac, 0xa6, 0x8e, 0xf3, 0xe6, 0xa5, 0x73, 0xf7, + 0xbf, 0xd9, 0x4f, 0xad, 0x72, 0x43, 0x47, 0xcf, 0xfb, 0x4c, 0x8b, 0x8e, 0x9b, 0xd5, 0x1c, 0x81, + 0xeb, 0x45, 0x96, 0x20, 0x89, 0xe1, 0x30, 0xe5, 0x11, 0x4a, 0xeb, 0x5b, 0xa0, 0x04, 0xf9, 0x07, + 0x94, 0x5a, 0x17, 0xda, 0x46, 0x67, 0xd9, 0xbf, 0x33, 0x2f, 0x9d, 0x8d, 0x2a, 0xf7, 0x34, 0xb5, + 0x1b, 0xae, 0x55, 0xf4, 0x13, 0xcd, 0xea, 0xff, 0xdd, 0xaf, 0x39, 0xf3, 0x0d, 0xb8, 0x46, 0xd1, + 0x18, 0xd6, 0xf5, 0x55, 0xa1, 0x24, 0x14, 0x0b, 0x6b, 0xa5, 0x6d, 0x74, 0x56, 0xfd, 0xf5, 0x79, + 0xe9, 0xdc, 0xf8, 0x77, 0x94, 0xc7, 0xe9, 0xdc, 0xf0, 0x0a, 0x45, 0xe3, 0xd7, 0x1a, 0xd7, 0xd6, + 0xaf, 0x14, 0xba, 0xb5, 0xf2, 0x65, 0xcf, 0x69, 0xfc, 0xd9, 0x73, 0x0c, 0x3f, 0xd8, 0x9f, 0xda, + 0xc6, 0xc1, 0xd4, 0x36, 0x7e, 0x4d, 0x6d, 0xe3, 0xf3, 0xcc, 0x6e, 0x1c, 0xcc, 0xec, 0xc6, 0x8f, + 0x99, 0xdd, 0x78, 0xbb, 0xb9, 0x70, 0x81, 0x23, 0x16, 0x75, 0xe3, 0x11, 0x22, 0xcc, 0x5b, 0xd8, + 0xf8, 0xb1, 0xda, 0x79, 0x7d, 0x91, 0xa3, 0xa6, 0xde, 0xd9, 0xfb, 0x7f, 0x03, 0x00, 0x00, 0xff, + 0xff, 0xc5, 0xe6, 0x36, 0x68, 0x11, 0x04, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -178,6 +202,12 @@ func (this *Params) Equal(that interface{}) bool { if this.NumOfLockupBlocksForMaintenance != that1.NumOfLockupBlocksForMaintenance { return false } + if this.UpdateGlobalPriceInterval != that1.UpdateGlobalPriceInterval { + return false + } + if this.MaxUpdatePriceTimes != that1.MaxUpdatePriceTimes { + return false + } return true } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -200,6 +230,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MaxUpdatePriceTimes != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MaxUpdatePriceTimes)) + i-- + dAtA[i] = 0x40 + } + if m.UpdateGlobalPriceInterval != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.UpdateGlobalPriceInterval)) + i-- + dAtA[i] = 0x38 + } if m.NumOfLockupBlocksForMaintenance != 0 { i = encodeVarintParams(dAtA, i, uint64(m.NumOfLockupBlocksForMaintenance)) i-- @@ -279,6 +319,12 @@ func (m *Params) Size() (n int) { if m.NumOfLockupBlocksForMaintenance != 0 { n += 1 + sovParams(uint64(m.NumOfLockupBlocksForMaintenance)) } + if m.UpdateGlobalPriceInterval != 0 { + n += 1 + sovParams(uint64(m.UpdateGlobalPriceInterval)) + } + if m.MaxUpdatePriceTimes != 0 { + n += 1 + sovParams(uint64(m.MaxUpdatePriceTimes)) + } return n } @@ -474,6 +520,44 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpdateGlobalPriceInterval", wireType) + } + m.UpdateGlobalPriceInterval = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UpdateGlobalPriceInterval |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxUpdatePriceTimes", wireType) + } + m.MaxUpdatePriceTimes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxUpdatePriceTimes |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/storage/client/cli/query_test.go b/x/storage/client/cli/query_test.go index 36141b89b..6a5b73e1e 100644 --- a/x/storage/client/cli/query_test.go +++ b/x/storage/client/cli/query_test.go @@ -3,13 +3,13 @@ package cli_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/client/flags" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/gogoproto/proto" "github.com/bnb-chain/greenfield/testutil/sample" "github.com/bnb-chain/greenfield/x/storage/client/cli" "github.com/bnb-chain/greenfield/x/storage/types" - "github.com/cosmos/cosmos-sdk/client/flags" ) func (s *CLITestSuite) TestQueryCmd() { diff --git a/x/storage/keeper/keeper_test.go b/x/storage/keeper/keeper_test.go index 5c0c44b2c..6188eddba 100644 --- a/x/storage/keeper/keeper_test.go +++ b/x/storage/keeper/keeper_test.go @@ -1,6 +1,8 @@ package keeper_test -import "github.com/bnb-chain/greenfield/testutil/sample" +import ( + "github.com/bnb-chain/greenfield/testutil/sample" +) func (s *TestSuite) TestClearDiscontinueBucketCount() { acc1 := sample.RandAccAddress() diff --git a/x/storage/keeper/payment.go b/x/storage/keeper/payment.go index 87d6953e4..b2fdd8c7d 100644 --- a/x/storage/keeper/payment.go +++ b/x/storage/keeper/payment.go @@ -3,13 +3,12 @@ package keeper import ( "fmt" - sptypes "github.com/bnb-chain/greenfield/x/sp/types" - "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/bnb-chain/greenfield/x/payment/types" + sptypes "github.com/bnb-chain/greenfield/x/sp/types" storagetypes "github.com/bnb-chain/greenfield/x/storage/types" vgtypes "github.com/bnb-chain/greenfield/x/virtualgroup/types" ) diff --git a/x/virtualgroup/client/cli/query_test.go b/x/virtualgroup/client/cli/query_test.go index 51838ba12..b8299e5d7 100644 --- a/x/virtualgroup/client/cli/query_test.go +++ b/x/virtualgroup/client/cli/query_test.go @@ -3,12 +3,12 @@ package cli_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/client/flags" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/gogoproto/proto" "github.com/bnb-chain/greenfield/x/virtualgroup/client/cli" "github.com/bnb-chain/greenfield/x/virtualgroup/types" - "github.com/cosmos/cosmos-sdk/client/flags" ) func (s *CLITestSuite) TestQueryCmd() {