From fb45cbfb18282bcbfb4e30f1908b0b4ed7a85a2a Mon Sep 17 00:00:00 2001 From: forcodedancing Date: Wed, 6 Nov 2024 20:13:38 -0600 Subject: [PATCH 1/3] fix: fail to resume frozen payment account when netflow is zero --- app/upgrade.go | 17 ++++ deployment/localup/localup.sh | 1 + e2e/tests/payment_test.go | 128 ++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- x/payment/keeper/stream_record.go | 11 ++- 6 files changed, 159 insertions(+), 4 deletions(-) diff --git a/app/upgrade.go b/app/upgrade.go index 92b78f462..745c8acb3 100644 --- a/app/upgrade.go +++ b/app/upgrade.go @@ -37,6 +37,7 @@ func (app *App) RegisterUpgradeHandlers(chainID string, serverCfg *serverconfig. app.registerVeldUpgradeHandler() app.registerMongolianUpgradeHandler() app.registerAltaiUpgradeHandler() + app.registerSavannaUpgradeHandler() // app.register...() // ... return nil @@ -313,3 +314,19 @@ func (app *App) registerAltaiUpgradeHandler() { return nil }) } + +func (app *App) registerSavannaUpgradeHandler() { + // Register the upgrade handler + app.UpgradeKeeper.SetUpgradeHandler(upgradetypes.Savanna, + func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + app.Logger().Info("upgrade to ", plan.Name) + return app.mm.RunMigrations(ctx, app.configurator, fromVM) + }) + + // Register the upgrade initializer + app.UpgradeKeeper.SetUpgradeInitializer(upgradetypes.Savanna, + func() error { + app.Logger().Info("Init Savanna upgrade") + return nil + }) +} diff --git a/deployment/localup/localup.sh b/deployment/localup/localup.sh index d3c7221bb..b4ad2b8ca 100644 --- a/deployment/localup/localup.sh +++ b/deployment/localup/localup.sh @@ -182,6 +182,7 @@ function generate_genesis() { echo -e '[[upgrade]]\nname = "Erdos"\nheight = 25\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml echo -e '[[upgrade]]\nname = "Veld"\nheight = 26\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml echo -e '[[upgrade]]\nname = "Mongolian"\nheight = 27\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml + echo -e '[[upgrade]]\nname = "Savanna"\nheight = 28\ninfo = ""' >> ${workspace}/.local/validator${i}/config/app.toml done # enable swagger API for validator0 diff --git a/e2e/tests/payment_test.go b/e2e/tests/payment_test.go index 575f32206..157bc6074 100644 --- a/e2e/tests/payment_test.go +++ b/e2e/tests/payment_test.go @@ -2170,6 +2170,134 @@ func (s *PaymentTestSuite) TestDiscontinue_MultiBuckets() { s.Require().True(streamRecordsAfter.User.LockBalance.IsZero()) } +func (s *PaymentTestSuite) TestDeposit_FrozenAccount_NetflowIsZero() { + defer s.revertParams() + + ctx := context.Background() + sp := s.PickStorageProvider() + gvg, found := sp.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, 1000000)[0] + + streamAddresses := []string{ + user.GetAddr().String(), + family.VirtualPaymentAddress, + gvg.VirtualPaymentAddress, + paymenttypes.ValidatorTaxPoolAddress.String(), + } + + // update params + params := s.queryParams() + params.VersionedParams.ReserveTime = 8 + params.ForcedSettleTime = 5 + s.updateParams(params) + + // create bucket + bucketName := s.createBucket(sp, gvg, user, 0) + + // create & seal objects + for i := 0; i < 2; i++ { + _, _, objectName1, objectId1, checksums1, _ := s.createObject(user, bucketName, false) + s.sealObject(sp, gvg, bucketName, objectName1, objectId1, checksums1) + queryHeadObjectRequest := storagetypes.QueryHeadObjectRequest{ + BucketName: bucketName, + ObjectName: objectName1, + } + queryHeadObjectResponse, err := s.Client.HeadObject(ctx, &queryHeadObjectRequest) + s.Require().NoError(err) + s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_SEALED) + time.Sleep(200 * time.Millisecond) + } + + // transfer out all balance + queryBalanceRequest := banktypes.QueryBalanceRequest{Denom: s.Config.Denom, Address: user.GetAddr().String()} + queryBalanceResponse, err := s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgSend := banktypes.NewMsgSend(user.GetAddr(), core.GenRandomAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.SubRaw(5*types.DecimalGwei)), + )) + + simulateResponse := s.SimulateTx(msgSend, user) + gasLimit := simulateResponse.GasInfo.GetGasUsed() + gasPrice, err := sdk.ParseCoinNormalized(simulateResponse.GasInfo.GetMinGasPrice()) + s.Require().NoError(err) + + msgSend.Amount = sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, queryBalanceResponse.Balance.Amount.Sub(gasPrice.Amount.Mul(sdk.NewInt(int64(gasLimit))))), + ) + s.SendTxBlock(user, msgSend) + queryBalanceResponse, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + s.Require().Equal(int64(0), queryBalanceResponse.Balance.Amount.Int64()) + + // wait account to be frozen + time.Sleep(8 * time.Second) + streamRecord := s.getStreamRecord(user.GetAddr().String()) + s.Require().True(streamRecord.Status == paymenttypes.STREAM_ACCOUNT_STATUS_FROZEN) + s.Require().True(streamRecord.NetflowRate.IsZero()) + s.Require().True(streamRecord.FrozenNetflowRate.IsNegative()) + + // force delete bucket + msgDiscontinueBucket := storagetypes.NewMsgDiscontinueBucket(sp.GcKey.GetAddr(), bucketName, "test") + txRes := s.SendTxBlock(sp.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") + streamRecordsAfter := s.getStreamRecords(streamAddresses) + s.Require().True(streamRecordsAfter.User.NetflowRate.IsZero()) + s.Require().True(streamRecordsAfter.User.FrozenNetflowRate.IsZero()) + s.Require().True(streamRecordsAfter.User.LockBalance.IsZero()) + s.Require().True(streamRecordsAfter.User.StaticBalance.IsZero()) + s.Require().True(streamRecordsAfter.User.BufferBalance.IsZero()) + + // deposit payment account + helper := s.GenAndChargeAccounts(1, 1000000)[0] + msgSend = banktypes.NewMsgSend(helper.GetAddr(), user.GetAddr(), sdk.NewCoins( + sdk.NewCoin(s.Config.Denom, sdk.NewInt(2e18)), + )) + s.SendTxBlock(helper, msgSend) + _, err = s.Client.BankQueryClient.Balance(ctx, &queryBalanceRequest) + s.Require().NoError(err) + + msgDeposit := &paymenttypes.MsgDeposit{ + Creator: user.GetAddr().String(), + To: user.GetAddr().String(), + Amount: sdk.NewInt(1e18), + } + _ = s.SendTxBlock(user, msgDeposit) + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().True(streamRecordsAfter.User.Status == paymenttypes.STREAM_ACCOUNT_STATUS_ACTIVE) + s.Require().True(streamRecordsAfter.User.StaticBalance.Equal(sdk.NewInt(1e18))) + s.Require().True(streamRecordsAfter.User.SettleTimestamp == 0) + + // create bucket with quota again + _ = s.createBucket(sp, gvg, user, 100) + streamRecordsAfter = s.getStreamRecords(streamAddresses) + s.Require().True(streamRecordsAfter.User.StaticBalance.LT(sdk.NewInt(1e18))) + s.Require().True(streamRecordsAfter.User.BufferBalance.GT(sdk.NewInt(0))) + s.Require().True(streamRecordsAfter.User.SettleTimestamp > 0) +} + func TestPaymentTestSuite(t *testing.T) { suite.Run(t, new(PaymentTestSuite)) } diff --git a/go.mod b/go.mod index f41d2fc61..1371b07c8 100644 --- a/go.mod +++ b/go.mod @@ -176,7 +176,7 @@ replace ( github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v1.3.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.9.2 + github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v1.9.3-0.20241106114330-708c5e70e9f3 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 d34773df7..aa6ef6509 100644 --- a/go.sum +++ b/go.sum @@ -163,8 +163,8 @@ github.com/bnb-chain/greenfield-cometbft v1.3.0 h1:v3nZ16ledTZGF5Csys7fTQGZcEV78 github.com/bnb-chain/greenfield-cometbft v1.3.0/go.mod h1:0D+VPivZTeBldjtGGi9LKbBnKEO/RtMRJikie92LkYI= 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.9.2 h1:hqZ4v4M3nkBNs1dXbAQkMBrNQuP9maQOSU+rBwzAemQ= -github.com/bnb-chain/greenfield-cosmos-sdk v1.9.2/go.mod h1:2bwmwdXYBISnQoMwgAcZTVGt21lMsHZSeeeMByTvDlQ= +github.com/bnb-chain/greenfield-cosmos-sdk v1.9.3-0.20241106114330-708c5e70e9f3 h1:76nYX3W9tcS4tGhk3kvVAkosQfDoaYiZZu5sKXY3nz0= +github.com/bnb-chain/greenfield-cosmos-sdk v1.9.3-0.20241106114330-708c5e70e9f3/go.mod h1:2bwmwdXYBISnQoMwgAcZTVGt21lMsHZSeeeMByTvDlQ= 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/payment/keeper/stream_record.go b/x/payment/keeper/stream_record.go index 1fb01a63e..eeba9772d 100644 --- a/x/payment/keeper/stream_record.go +++ b/x/payment/keeper/stream_record.go @@ -380,8 +380,18 @@ func (k Keeper) TryResumeStreamRecord(ctx sdk.Context, streamRecord *types.Strea reserveTime := params.VersionedParams.ReserveTime forcedSettleTime := params.ForcedSettleTime + now := ctx.BlockTime().Unix() totalRate := streamRecord.NetflowRate.Add(streamRecord.FrozenNetflowRate) streamRecord.StaticBalance = streamRecord.StaticBalance.Add(depositBalance) + + if totalRate.IsZero() && ctx.IsUpgraded(upgradetypes.Savanna) { + streamRecord.Status = types.STREAM_ACCOUNT_STATUS_ACTIVE + streamRecord.CrudTimestamp = now + streamRecord.SettleTimestamp = 0 + k.SetStreamRecord(ctx, streamRecord) + return nil + } + expectedBalanceToResume := totalRate.Neg().Mul(sdkmath.NewIntFromUint64(reserveTime)) if streamRecord.StaticBalance.LT(expectedBalanceToResume) { // deposit balance is not enough to resume, only add static balance @@ -389,7 +399,6 @@ func (k Keeper) TryResumeStreamRecord(ctx sdk.Context, streamRecord *types.Strea return nil } - now := ctx.BlockTime().Unix() prevSettleTime := streamRecord.SettleTimestamp streamRecord.SettleTimestamp = now + streamRecord.StaticBalance.Quo(totalRate.Abs()).Int64() - int64(forcedSettleTime) streamRecord.BufferBalance = expectedBalanceToResume From 53c4ad9159d72ad59873c0afc0c77d0052a81b40 Mon Sep 17 00:00:00 2001 From: forcodedancing Date: Thu, 7 Nov 2024 13:16:56 -0600 Subject: [PATCH 2/3] try to fix e2e issue --- e2e/tests/payment_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/e2e/tests/payment_test.go b/e2e/tests/payment_test.go index 157bc6074..351aef9b0 100644 --- a/e2e/tests/payment_test.go +++ b/e2e/tests/payment_test.go @@ -376,6 +376,8 @@ func (s *PaymentTestSuite) TestDeposit_ActiveAccount() { Add(paymentAccountStreamRecordAfter.BufferBalance.Sub(paymentAccountStreamRecord.BufferBalance)) s.Require().Equal(settledBalance.Add(paymentBalanceChange).Int64(), paymentAccountBNBNeeded.Int64()) s.Require().Equal(paymentAccountBNBNeeded.MulRaw(3), settledBalance.Add(paymentAccountStreamRecordAfter.StaticBalance.Add(paymentAccountStreamRecordAfter.BufferBalance))) + + _ = s.deleteBucket(user, bucketName) } func (s *PaymentTestSuite) TestDeposit_FromBankAccount() { @@ -2291,11 +2293,15 @@ func (s *PaymentTestSuite) TestDeposit_FrozenAccount_NetflowIsZero() { s.Require().True(streamRecordsAfter.User.SettleTimestamp == 0) // create bucket with quota again - _ = s.createBucket(sp, gvg, user, 100) + bucketName = s.createBucket(sp, gvg, user, 100) streamRecordsAfter = s.getStreamRecords(streamAddresses) s.Require().True(streamRecordsAfter.User.StaticBalance.LT(sdk.NewInt(1e18))) s.Require().True(streamRecordsAfter.User.BufferBalance.GT(sdk.NewInt(0))) s.Require().True(streamRecordsAfter.User.SettleTimestamp > 0) + + // delete bucket + err = s.deleteBucket(user, bucketName) + s.Require().Error(err) } func TestPaymentTestSuite(t *testing.T) { From 1fa7d0fca9a4e5a6830215ded33bfab25b59c7fb Mon Sep 17 00:00:00 2001 From: Annie <108039750+annielz@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:32:45 +0800 Subject: [PATCH 3/3] release: prepare for release v1.10.0 (#648) --- CHANGELOG.md | 6 ++++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54b46a0a5..54b7800c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## V1.10.0 +This release introduces the Savanna upgrade. + +Fixes: +* [#647] https://github.com/bnb-chain/greenfield/pull/647 fix: fail to resume frozen payment account when netflow is zero + ## V1.9.1 This release introduces the Altai upgrade. diff --git a/go.mod b/go.mod index 1371b07c8..4583d9b53 100644 --- a/go.mod +++ b/go.mod @@ -176,7 +176,7 @@ replace ( github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v1.3.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.9.3-0.20241106114330-708c5e70e9f3 + github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v1.10.0 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 aa6ef6509..1959d78b1 100644 --- a/go.sum +++ b/go.sum @@ -163,8 +163,8 @@ github.com/bnb-chain/greenfield-cometbft v1.3.0 h1:v3nZ16ledTZGF5Csys7fTQGZcEV78 github.com/bnb-chain/greenfield-cometbft v1.3.0/go.mod h1:0D+VPivZTeBldjtGGi9LKbBnKEO/RtMRJikie92LkYI= 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.9.3-0.20241106114330-708c5e70e9f3 h1:76nYX3W9tcS4tGhk3kvVAkosQfDoaYiZZu5sKXY3nz0= -github.com/bnb-chain/greenfield-cosmos-sdk v1.9.3-0.20241106114330-708c5e70e9f3/go.mod h1:2bwmwdXYBISnQoMwgAcZTVGt21lMsHZSeeeMByTvDlQ= +github.com/bnb-chain/greenfield-cosmos-sdk v1.10.0 h1:uWmy80c8kvvvmUb50hgo2kX4QLcmvqs9J5tLvCgXnIs= +github.com/bnb-chain/greenfield-cosmos-sdk v1.10.0/go.mod h1:2bwmwdXYBISnQoMwgAcZTVGt21lMsHZSeeeMByTvDlQ= 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=