Skip to content

Commit

Permalink
fix: fix lock balance not updated for frozen payment account (#382)
Browse files Browse the repository at this point in the history
  • Loading branch information
forcodedancing authored Jul 27, 2023
1 parent 62637a7 commit af7c346
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
5 changes: 5 additions & 0 deletions e2e/tests/payment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3009,6 +3009,8 @@ func (s *PaymentTestSuite) TestDiscontinue_InBlocks_WithPriceChangeReserveTimeCh
s.Require().Equal(queryHeadObjectResponse.ObjectInfo.ObjectStatus, storagetypes.OBJECT_STATUS_CREATED)
time.Sleep(200 * time.Millisecond)
}
userStreamRecord := s.getStreamRecord(user.GetAddr().String())
s.Require().True(userStreamRecord.LockBalance.IsPositive())

// update new price
msgUpdatePrice := &sptypes.MsgUpdateSpStoragePrice{
Expand Down Expand Up @@ -3107,6 +3109,9 @@ func (s *PaymentTestSuite) TestDiscontinue_InBlocks_WithPriceChangeReserveTimeCh
s.Require().Equal(streamRecordsAfter.GVG.NetflowRate.Sub(streamRecordsBefore.GVG.NetflowRate).Int64(), int64(0))
s.Require().True(streamRecordsAfter.Tax.NetflowRate.Sub(streamRecordsBefore.Tax.NetflowRate).Int64() <= int64(0)) // there are other auto settling

s.Require().True(streamRecordsAfter.User.LockBalance.IsZero())
s.Require().True(streamRecordsAfter.User.StaticBalance.Int64() == userStreamRecord.LockBalance.Int64())

// revert price
msgUpdatePrice = &sptypes.MsgUpdateSpStoragePrice{
SpAddress: sp.OperatorKey.GetAddr().String(),
Expand Down
2 changes: 1 addition & 1 deletion x/payment/keeper/storage_fee_charge.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (k Keeper) applyFrozenUserFlows(ctx sdk.Context, userFlows types.UserFlows,
}
streamRecordChange := types.NewDefaultStreamRecordChangeWithAddr(from).
WithRateChange(totalActiveRate.Neg()).WithFrozenRateChange(totalFrozenRate.Neg())
err := k.UpdateFrozenStreamRecord(ctx, streamRecord, streamRecordChange)
err := k.UpdateStreamRecord(ctx, streamRecord, streamRecordChange)
if err != nil {
return fmt.Errorf("apply stream record changes for user failed: %w", err)
}
Expand Down
20 changes: 13 additions & 7 deletions x/payment/keeper/stream_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ func (k Keeper) GetAllStreamRecord(ctx sdk.Context) (list []types.StreamRecord)
// it only handles the lock balance change and ignore the other changes(since the streams are already changed and the
// accumulated OutFlows are changed outside this function)
func (k Keeper) UpdateFrozenStreamRecord(ctx sdk.Context, streamRecord *types.StreamRecord, change *types.StreamRecordChange) error {
forced, _ := ctx.Value(types.ForceUpdateStreamRecordKey).(bool)
if !forced {
return fmt.Errorf("stream record %s is frozen", streamRecord.Account)
}
// update lock balance
if !change.LockBalanceChange.IsZero() {
streamRecord.LockBalance = streamRecord.LockBalance.Add(change.LockBalanceChange)
Expand All @@ -132,6 +136,10 @@ func (k Keeper) UpdateFrozenStreamRecord(ctx sdk.Context, streamRecord *types.St
}

func (k Keeper) UpdateStreamRecord(ctx sdk.Context, streamRecord *types.StreamRecord, change *types.StreamRecordChange) error {
if streamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN {
return k.UpdateFrozenStreamRecord(ctx, streamRecord, change)
}

forced, _ := ctx.Value(types.ForceUpdateStreamRecordKey).(bool) // force update in end block
isPay := change.StaticBalanceChange.IsNegative() || change.RateChange.IsNegative()
currentTimestamp := ctx.BlockTime().Unix()
Expand Down Expand Up @@ -217,13 +225,11 @@ func (k Keeper) UpdateStreamRecordByAddr(ctx sdk.Context, change *types.StreamRe

func (k Keeper) ForceSettle(ctx sdk.Context, streamRecord *types.StreamRecord) error {
totalBalance := streamRecord.StaticBalance.Add(streamRecord.BufferBalance)
if totalBalance.IsPositive() {
change := types.NewDefaultStreamRecordChangeWithAddr(types.GovernanceAddress).WithStaticBalanceChange(totalBalance)
_, err := k.UpdateStreamRecordByAddr(ctx, change)
if err != nil {
telemetry.IncrCounter(1, types.GovernanceAddressLackBalanceLabel)
return fmt.Errorf("update governance stream record failed: %w", err)
}
change := types.NewDefaultStreamRecordChangeWithAddr(types.GovernanceAddress).WithStaticBalanceChange(totalBalance)
_, err := k.UpdateStreamRecordByAddr(ctx, change)
if err != nil {
telemetry.IncrCounter(1, types.GovernanceAddressLackBalanceLabel)
return fmt.Errorf("update governance stream record failed: %w", err)
}
// force settle
streamRecord.StaticBalance = sdkmath.ZeroInt()
Expand Down
37 changes: 37 additions & 0 deletions x/payment/keeper/stream_record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,3 +752,40 @@ func TestAutoSettle_SettleInMultipleBlocks_AutoResumeExists(t *testing.T) {
require.Equal(t, gvg3StreamRecord.NetflowRate, sdk.NewInt(150))
require.Equal(t, gvg3StreamRecord.FrozenNetflowRate, sdkmath.ZeroInt())
}

func TestUpdateStreamRecord_FrozenAccountLockBalance(t *testing.T) {
keeper, ctx, _ := makePaymentKeeper(t)
ctx = ctx.WithBlockTime(time.Now())

user := sample.RandAccAddress()
streamRecord := &types.StreamRecord{
StaticBalance: sdkmath.ZeroInt(),
BufferBalance: sdkmath.ZeroInt(),
LockBalance: sdkmath.NewInt(1000),
Account: user.String(),
Status: types.STREAM_ACCOUNT_STATUS_FROZEN,
NetflowRate: sdkmath.NewInt(0),
FrozenNetflowRate: sdkmath.NewInt(100).Neg(),
OutFlowCount: 1,
}
keeper.SetStreamRecord(ctx, streamRecord)

// update fail when no force flag
change := types.NewDefaultStreamRecordChangeWithAddr(user).
WithLockBalanceChange(streamRecord.LockBalance.Neg())
_, err := keeper.UpdateStreamRecordByAddr(ctx, change)
require.ErrorContains(t, err, "is frozen")

// update success when there is force flag
ctx = ctx.WithValue(types.ForceUpdateStreamRecordKey, true)
change = types.NewDefaultStreamRecordChangeWithAddr(user).
WithLockBalanceChange(streamRecord.LockBalance.Neg())
_, err = keeper.UpdateStreamRecordByAddr(ctx, change)
require.NoError(t, err)

streamRecord, _ = keeper.GetStreamRecord(ctx, user)
require.True(t, streamRecord.Status == types.STREAM_ACCOUNT_STATUS_FROZEN)
require.True(t, streamRecord.LockBalance.IsZero())
require.True(t, streamRecord.StaticBalance.Int64() == 1000)

}

0 comments on commit af7c346

Please sign in to comment.