Skip to content

Commit

Permalink
refactor codes to update global price in each month
Browse files Browse the repository at this point in the history
  • Loading branch information
forcodedancing committed Aug 14, 2023
1 parent 0be796d commit 2e40403
Show file tree
Hide file tree
Showing 17 changed files with 394 additions and 197 deletions.
3 changes: 3 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,9 @@ func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.R

// EndBlocker application updates every end block
func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
lastBlockTime := app.GetCheckState().Context().BlockHeader().Time.Unix()
ctx = ctx.WithValue(spmodule.LastBlockTimeKey, lastBlockTime)

resp := app.mm.EndBlock(ctx, req)
bankIavl, _ := app.CommitMultiStore().GetCommitStore(sdk.NewKVStoreKey(banktypes.StoreKey)).(*iavl.Store)
paymentIavl, _ := app.CommitMultiStore().GetCommitStore(sdk.NewKVStoreKey(paymentmoduletypes.StoreKey)).(*iavl.Store)
Expand Down
2 changes: 1 addition & 1 deletion deployment/localup/localup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ 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/\"update_global_price_interval\": \"0\"/\"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
Expand Down
153 changes: 27 additions & 126 deletions e2e/tests/storage_bill_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1760,13 +1760,14 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket() {
family := queryFamilyResponse.GlobalVirtualGroupFamily
user := s.GenAndChargeAccounts(1, 10)[0]

streamAddresses0 := []string{
streamAddresses := []string{
user.GetAddr().String(),
family.VirtualPaymentAddress,
gvg.VirtualPaymentAddress,
paymenttypes.ValidatorTaxPoolAddress.String(),
}

streamAddresses0 := streamAddresses
paymentParams, err := s.Client.PaymentQueryClient.Params(ctx, &paymenttypes.QueryParamsRequest{})
s.T().Logf("paymentParams %s, err: %v", paymentParams, err)
s.Require().NoError(err)
Expand All @@ -1778,11 +1779,11 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket() {
s.Require().NoError(err)

// create object with none zero payload size
streamRecordsBefore := s.getStreamRecords(streamAddresses0)
streamRecordsBefore := s.getStreamRecords(streamAddresses)
_, _, objectName, objectId, checksums, payloadSize := s.createObject(user, bucketName, false)

// assertions
streamRecordsAfter := s.getStreamRecords(streamAddresses0)
streamRecordsAfter := s.getStreamRecords(streamAddresses)
s.Require().Equal(streamRecordsAfter.User.StaticBalance, sdkmath.ZeroInt())
lockFee := s.calculateLockFee(bucketName, objectName, payloadSize)
s.Require().Equal(streamRecordsAfter.User.LockBalance.Sub(streamRecordsBefore.User.LockBalance), lockFee)
Expand All @@ -1795,7 +1796,7 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket() {
s.sealObject(primarySP, gvg, bucketName, objectName, objectId, checksums)

// assertions
streamRecordsAfter = s.getStreamRecords(streamAddresses0)
streamRecordsAfter = s.getStreamRecords(streamAddresses)
gvgFamilyRate, gvgRate, taxRate, userTotalRate := s.calculateStorageRates(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())
Expand Down Expand Up @@ -1831,30 +1832,28 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket() {
FamilyId: dstGVG.FamilyId,
})
s.Require().NoError(err)
dstFamily := queryFamilyResponse.GlobalVirtualGroupFamily

streamAddresses1 := []string{
family = queryFamilyResponse.GlobalVirtualGroupFamily
streamAddresses = []string{
user.GetAddr().String(),
dstFamily.VirtualPaymentAddress,
family.VirtualPaymentAddress,
dstGVG.VirtualPaymentAddress,
paymenttypes.ValidatorTaxPoolAddress.String(),
}
streamRecordsBefore = s.getStreamRecords(streamAddresses1)

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
// MigrationBucket
msgMigrationBucket, msgCompleteMigrationBucket := s.NewMigrateBucket(primarySP, dstPrimarySP, user, bucketName, gvg.FamilyId, dstGVG.FamilyId, bucketInfo.BucketInfo.Id)
s.SendTxBlock(user, msgMigrationBucket)
s.Require().NoError(err)

// complete MigrateBucket
// complete MigrationBucket
s.SendTxBlock(dstPrimarySP.OperatorKey, msgCompleteMigrationBucket)

streamRecordsAfter = s.getStreamRecords(streamAddresses1)
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))
Expand All @@ -1871,36 +1870,29 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket() {
s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate), taxRate.Sub(taxRate0))
s.Require().Equal(streamRecordsAfter.User.NetflowRate.Neg(), userTotalRate.Abs())

// try to migrate again
// set price
s.updateGlobalSpPrice(priceRes.GlobalSpStorePrice.ReadPrice.MulInt64(120), priceRes.GlobalSpStorePrice.PrimaryStorePrice.MulInt64(5000))

queryBalanceRequest.Address = dstPrimarySP.FundingKey.GetAddr().String()
fundBalanceBefore, err = s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest)
s.Require().NoError(err)
streamRecordsBefore = s.getStreamRecords(streamAddresses0)

// send msgMigrateBucket
// send msgMigrationBucket
msgMigrationBucket, msgCompleteMigrationBucket = s.NewMigrateBucket(dstPrimarySP, primarySP, user, bucketName, dstGVG.FamilyId, gvg.FamilyId, bucketInfo.BucketInfo.Id)
s.SendTxBlock(user, msgMigrationBucket)

s.SendTxBlock(user, msgMigrationBucket)
s.Require().NoError(err)
s.reduceBNBBalance(user, s.Validator, sdkmath.NewIntWithDecimal(1, 1))

s.SendTxBlock(primarySP.OperatorKey, msgCompleteMigrationBucket)
// account will be frozen
streamRecordsAfter = s.getStreamRecords(streamAddresses0)
s.Require().Equal(streamRecordsAfter.User.Status, paymenttypes.STREAM_ACCOUNT_STATUS_FROZEN)
s.SendTxBlockWithExpectErrorString(msgCompleteMigrationBucket, primarySP.OperatorKey, "apply stream record changes for user failed")

s.updateGlobalSpPrice(priceRes.GlobalSpStorePrice.ReadPrice.MulInt64(10), priceRes.GlobalSpStorePrice.PrimaryStorePrice.MulInt64(10))
readPrice, primaryPrice, secondaryPrice := s.getPrices(time.Now().Unix())
s.T().Logf("readPrice: %v, primaryPrice: %v,secondaryPrice: %v", readPrice, primaryPrice, secondaryPrice)

// deposit to the account
s.transferBNB(s.Validator, user, sdkmath.NewIntWithDecimal(10000, 18))
msgDeposit := &paymenttypes.MsgDeposit{
Creator: user.GetAddr().String(),
To: user.GetAddr().String(),
Amount: sdkmath.NewIntWithDecimal(1000, 18),
}
_ = s.SendTxBlock(user, msgDeposit)
streamRecordsAfter = s.getStreamRecords(streamAddresses0)
s.Require().Equal(streamRecordsAfter.User.Status, paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE)

s.SendTxBlock(primarySP.OperatorKey, msgCompleteMigrationBucket)
streamRecordsAfter = s.getStreamRecords(streamAddresses0)
fundBalanceAfter, err = s.Client.BankQueryClient.Balance(context.Background(), &queryBalanceRequest)
s.Require().NoError(err)
Expand All @@ -1911,6 +1903,7 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket() {
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.User.LockBalance, sdkmath.ZeroInt())
s.Require().Equal(streamRecordsAfter.GVGFamily.NetflowRate.Sub(streamRecordsBefore.GVGFamily.NetflowRate), gvgFamilyRate)
s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate), gvgRate)
Expand Down Expand Up @@ -2066,7 +2059,7 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket_LockedFee_ThenDiscontin
s.Require().ErrorContains(err, "No such bucket")
}

func (s *PaymentTestSuite) TestStorageBill_MigrateBucket_FrozenAccount_ThenDiscontinueBucket() {
func (s *PaymentTestSuite) TestStorageBill_MigrateBucket_FrozenAccount_NotAllowed() {
var err error
ctx := context.Background()
primarySP := s.PickStorageProvider()
Expand Down Expand Up @@ -2157,16 +2150,6 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket_FrozenAccount_ThenDisco
s.Require().Equal(paymentAccountStreamRecordAfterAutoSettle.FrozenNetflowRate.Int64(), readTotalRate.Neg().Int64())

dstPrimarySP := s.CreateNewStorageProvider()
// update price
priceRes, err := s.Client.QueryGlobalSpStorePriceByTime(ctx, &sptypes.QueryGlobalSpStorePriceByTimeRequest{
Timestamp: 0,
})
s.Require().NoError(err)
s.T().Log("price", priceRes.GlobalSpStorePrice)

s.updateGlobalSpPrice(priceRes.GlobalSpStorePrice.ReadPrice.MulInt64(10), priceRes.GlobalSpStorePrice.PrimaryStorePrice.MulInt64(10000))
defer s.updateGlobalSpPrice(priceRes.GlobalSpStorePrice.ReadPrice, priceRes.GlobalSpStorePrice.PrimaryStorePrice)

_, secondarySPIDs := s.GetSecondarySP(dstPrimarySP, primarySP)
gvgID, _ := s.BaseSuite.CreateGlobalVirtualGroup(dstPrimarySP, 0, secondarySPIDs, 1)
gvgResp, err := s.Client.VirtualGroupQueryClient.GlobalVirtualGroup(context.Background(), &virtualgrouptypes.QueryGlobalVirtualGroupRequest{
Expand All @@ -2176,91 +2159,9 @@ func (s *PaymentTestSuite) TestStorageBill_MigrateBucket_FrozenAccount_ThenDisco
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(),
}
streamRecordsBefore := s.getStreamRecords(streamAddresses)

fundAddress := primarySP.FundingKey.GetAddr()
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)

time.Sleep(1 * time.Second)
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.calculateReadRatesCurrentTimestamp(bucketName)
s.T().Logf("gvgFamilyRate: %v, taxRate: %v, userTotalRate: %v", gvgFamilyRate, taxRate, userTotalRate)

expectedOutFlows := []paymenttypes.OutFlow{
{ToAddress: family.VirtualPaymentAddress, Rate: gvgFamilyRate, Status: paymenttypes.OUT_FLOW_STATUS_FROZEN},
{ToAddress: paymenttypes.ValidatorTaxPoolAddress.String(), Rate: taxRate, Status: paymenttypes.OUT_FLOW_STATUS_FROZEN},
}
userOutFlowsResponse, err := s.Client.OutFlows(ctx, &paymenttypes.QueryOutFlowsRequest{Account: paymentAddr})
s.Require().NoError(err)
sort.Slice(userOutFlowsResponse.OutFlows, func(i, j int) bool {
return userOutFlowsResponse.OutFlows[i].ToAddress < userOutFlowsResponse.OutFlows[j].ToAddress
})
sort.Slice(expectedOutFlows, func(i, j int) bool {
return expectedOutFlows[i].ToAddress < expectedOutFlows[j].ToAddress
})
s.Require().Equal(expectedOutFlows, userOutFlowsResponse.OutFlows)

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).Int64(), int64(0))
s.Require().Equal(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64(), int64(0))
s.Require().Equal(streamRecordsAfter.User.FrozenNetflowRate.Neg(), userTotalRate.Abs())
s.Require().Equal(streamRecordsAfter.User.NetflowRate.Neg(), sdkmath.ZeroInt())

// 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")

// check streams after delete
streamRecordsAfter = s.getStreamRecords(streamAddresses)
s.Require().Equal(streamRecordsAfter.User.FrozenNetflowRate.Neg(), sdkmath.ZeroInt())
s.Require().Equal(streamRecordsAfter.User.NetflowRate.Neg(), sdkmath.ZeroInt())
s.Require().Equal(streamRecordsAfter.User.OutFlowCount, uint64(0))
msgMigrateBucket, _ := s.NewMigrateBucket(primarySP, dstPrimarySP, user, bucketName, gvg.FamilyId, dstGVG.FamilyId, bucketInfo.BucketInfo.Id)
s.SendTxBlockWithExpectErrorString(msgMigrateBucket, user, "frozen")
}

func (s *PaymentTestSuite) GetSecondarySP(sps ...*core.StorageProvider) ([]*core.StorageProvider, []uint32) {
Expand Down
2 changes: 1 addition & 1 deletion proto/greenfield/sp/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ 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
// the time interval to update global storage price, if it is not set then the price will be updated at the first block of each natural month
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\""];
Expand Down
15 changes: 12 additions & 3 deletions swagger/static/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1659,7 +1659,10 @@ paths:
update_global_price_interval:
type: string
format: uint64
title: the time interval to update global storage price
title: >-
the time interval to update global storage price, if it is
not set then the price will be updated at the first block
of each natural month
max_update_price_times:
type: integer
format: int64
Expand Down Expand Up @@ -32854,7 +32857,10 @@ definitions:
update_global_price_interval:
type: string
format: uint64
title: the time interval to update global storage price
title: >-
the time interval to update global storage price, if it is not set
then the price will be updated at the first block of each natural
month
max_update_price_times:
type: integer
format: int64
Expand Down Expand Up @@ -32919,7 +32925,10 @@ definitions:
update_global_price_interval:
type: string
format: uint64
title: the time interval to update global storage price
title: >-
the time interval to update global storage price, if it is not set
then the price will be updated at the first block of each natural
month
max_update_price_times:
type: integer
format: int64
Expand Down
49 changes: 0 additions & 49 deletions x/payment/types/price.go

This file was deleted.

Loading

0 comments on commit 2e40403

Please sign in to comment.