Skip to content

Commit 529f9cf

Browse files
committed
feat(x/auth/vesting): change TrackDelegation and TrackUndelegation to return errors instead of panicking
- Update TrackDelegation and TrackUndelegation methods to return errors - Modify all vesting account implementations accordingly - Add proper error handling in bank keeper - Update tests to expect errors instead of panics Signed-off-by: Hwangjae Lee <[email protected]>
1 parent b6b58e4 commit 529f9cf

File tree

5 files changed

+151
-92
lines changed

5 files changed

+151
-92
lines changed

x/auth/vesting/exported/exported.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ type VestingAccount interface {
2222
// delegating from a vesting account. It accepts the current block time, the
2323
// delegation amount and balance of all coins whose denomination exists in
2424
// the account's original vesting balance.
25-
TrackDelegation(blockTime time.Time, balance, amount sdk.Coins)
25+
// Returns an error if the delegation is invalid (e.g., zero amount or insufficient funds).
26+
TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) error
2627

2728
// TrackUndelegation performs internal vesting accounting necessary when a
2829
// vesting account performs an undelegation.
29-
TrackUndelegation(amount sdk.Coins)
30+
// Returns an error if the undelegation is invalid (e.g., zero amount).
31+
TrackUndelegation(amount sdk.Coins) error
3032

3133
GetVestedCoins(blockTime time.Time) sdk.Coins
3234
GetVestingCoins(blockTime time.Time) sdk.Coins

x/auth/vesting/types/vesting_account.go

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,19 @@ func (bva BaseVestingAccount) LockedCoinsFromVesting(vestingCoins sdk.Coins) sdk
5656
//
5757
// CONTRACT: The account's coins, delegation coins, vesting coins, and delegated
5858
// vesting coins must be sorted.
59-
func (bva *BaseVestingAccount) TrackDelegation(balance, vestingCoins, amount sdk.Coins) {
59+
func (bva *BaseVestingAccount) TrackDelegation(balance, vestingCoins, amount sdk.Coins) error {
6060
for _, coin := range amount {
6161
baseAmt := balance.AmountOf(coin.Denom)
6262
vestingAmt := vestingCoins.AmountOf(coin.Denom)
6363
delVestingAmt := bva.DelegatedVesting.AmountOf(coin.Denom)
6464

65-
// Panic if the delegation amount is zero or if the base coins does not
65+
// Return error if the delegation amount is zero or if the base coins does not
6666
// exceed the desired delegation amount.
67-
if coin.Amount.IsZero() || baseAmt.LT(coin.Amount) {
68-
panic("delegation attempt with zero coins or insufficient funds")
67+
if coin.Amount.IsZero() {
68+
return fmt.Errorf("delegation attempt with zero coins")
69+
}
70+
if baseAmt.LT(coin.Amount) {
71+
return fmt.Errorf("delegation attempt with insufficient funds: balance %s, requested %s", baseAmt, coin.Amount)
6972
}
7073

7174
// compute x and y per the specification, where:
@@ -84,6 +87,7 @@ func (bva *BaseVestingAccount) TrackDelegation(balance, vestingCoins, amount sdk
8487
bva.DelegatedFree = bva.DelegatedFree.Add(yCoin)
8588
}
8689
}
90+
return nil
8791
}
8892

8993
// TrackUndelegation tracks an undelegation amount by setting the necessary
@@ -96,11 +100,11 @@ func (bva *BaseVestingAccount) TrackDelegation(balance, vestingCoins, amount sdk
96100
// the undelegated tokens are non-integral.
97101
//
98102
// CONTRACT: The account's coins and undelegation coins must be sorted.
99-
func (bva *BaseVestingAccount) TrackUndelegation(amount sdk.Coins) {
103+
func (bva *BaseVestingAccount) TrackUndelegation(amount sdk.Coins) error {
100104
for _, coin := range amount {
101-
// panic if the undelegation amount is zero
105+
// Return error if the undelegation amount is zero
102106
if coin.Amount.IsZero() {
103-
panic("undelegation attempt with zero coins")
107+
return fmt.Errorf("undelegation attempt with zero coins")
104108
}
105109
delegatedFree := bva.DelegatedFree.AmountOf(coin.Denom)
106110
delegatedVesting := bva.DelegatedVesting.AmountOf(coin.Denom)
@@ -121,6 +125,7 @@ func (bva *BaseVestingAccount) TrackUndelegation(amount sdk.Coins) {
121125
bva.DelegatedVesting = bva.DelegatedVesting.Sub(yCoin)
122126
}
123127
}
128+
return nil
124129
}
125130

126131
// GetOriginalVesting returns a vesting account's original vesting amount
@@ -235,8 +240,8 @@ func (cva ContinuousVestingAccount) LockedCoins(blockTime time.Time) sdk.Coins {
235240
// TrackDelegation tracks a desired delegation amount by setting the appropriate
236241
// values for the amount of delegated vesting, delegated free, and reducing the
237242
// overall amount of base coins.
238-
func (cva *ContinuousVestingAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) {
239-
cva.BaseVestingAccount.TrackDelegation(balance, cva.GetVestingCoins(blockTime), amount)
243+
func (cva *ContinuousVestingAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) error {
244+
return cva.BaseVestingAccount.TrackDelegation(balance, cva.GetVestingCoins(blockTime), amount)
240245
}
241246

242247
// GetStartTime returns the time when vesting starts for a continuous vesting
@@ -340,8 +345,8 @@ func (pva PeriodicVestingAccount) LockedCoins(blockTime time.Time) sdk.Coins {
340345
// TrackDelegation tracks a desired delegation amount by setting the appropriate
341346
// values for the amount of delegated vesting, delegated free, and reducing the
342347
// overall amount of base coins.
343-
func (pva *PeriodicVestingAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) {
344-
pva.BaseVestingAccount.TrackDelegation(balance, pva.GetVestingCoins(blockTime), amount)
348+
func (pva *PeriodicVestingAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) error {
349+
return pva.BaseVestingAccount.TrackDelegation(balance, pva.GetVestingCoins(blockTime), amount)
345350
}
346351

347352
// GetStartTime returns the time when vesting starts for a periodic vesting
@@ -439,8 +444,8 @@ func (dva DelayedVestingAccount) LockedCoins(blockTime time.Time) sdk.Coins {
439444
// TrackDelegation tracks a desired delegation amount by setting the appropriate
440445
// values for the amount of delegated vesting, delegated free, and reducing the
441446
// overall amount of base coins.
442-
func (dva *DelayedVestingAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) {
443-
dva.BaseVestingAccount.TrackDelegation(balance, dva.GetVestingCoins(blockTime), amount)
447+
func (dva *DelayedVestingAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) error {
448+
return dva.BaseVestingAccount.TrackDelegation(balance, dva.GetVestingCoins(blockTime), amount)
444449
}
445450

446451
// GetStartTime returns zero since a delayed vesting account has no start time.
@@ -495,8 +500,8 @@ func (plva PermanentLockedAccount) LockedCoins(_ time.Time) sdk.Coins {
495500
// TrackDelegation tracks a desired delegation amount by setting the appropriate
496501
// values for the amount of delegated vesting, delegated free, and reducing the
497502
// overall amount of base coins.
498-
func (plva *PermanentLockedAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) {
499-
plva.BaseVestingAccount.TrackDelegation(balance, plva.OriginalVesting, amount)
503+
func (plva *PermanentLockedAccount) TrackDelegation(blockTime time.Time, balance, amount sdk.Coins) error {
504+
return plva.BaseVestingAccount.TrackDelegation(balance, plva.OriginalVesting, amount)
500505
}
501506

502507
// GetStartTime returns zero since a permanent locked vesting account has no start time.

0 commit comments

Comments
 (0)