github.com/cosmos/cosmos-sdk@v0.50.10/x/distribution/keeper/hooks.go (about)

     1  package keeper
     2  
     3  import (
     4  	"context"
     5  
     6  	sdkmath "cosmossdk.io/math"
     7  
     8  	sdk "github.com/cosmos/cosmos-sdk/types"
     9  	"github.com/cosmos/cosmos-sdk/x/distribution/types"
    10  	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
    11  )
    12  
    13  // Wrapper struct
    14  type Hooks struct {
    15  	k Keeper
    16  }
    17  
    18  var _ stakingtypes.StakingHooks = Hooks{}
    19  
    20  // Create new distribution hooks
    21  func (k Keeper) Hooks() Hooks {
    22  	return Hooks{k}
    23  }
    24  
    25  // initialize validator distribution record
    26  func (h Hooks) AfterValidatorCreated(ctx context.Context, valAddr sdk.ValAddress) error {
    27  	val, err := h.k.stakingKeeper.Validator(ctx, valAddr)
    28  	if err != nil {
    29  		return err
    30  	}
    31  	return h.k.initializeValidator(ctx, val)
    32  }
    33  
    34  // AfterValidatorRemoved performs clean up after a validator is removed
    35  func (h Hooks) AfterValidatorRemoved(ctx context.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) error {
    36  	// fetch outstanding
    37  	outstanding, err := h.k.GetValidatorOutstandingRewardsCoins(ctx, valAddr)
    38  	if err != nil {
    39  		return err
    40  	}
    41  
    42  	// force-withdraw commission
    43  	valCommission, err := h.k.GetValidatorAccumulatedCommission(ctx, valAddr)
    44  	if err != nil {
    45  		return err
    46  	}
    47  
    48  	commission := valCommission.Commission
    49  
    50  	if !commission.IsZero() {
    51  		// subtract from outstanding
    52  		outstanding = outstanding.Sub(commission)
    53  
    54  		// split into integral & remainder
    55  		coins, remainder := commission.TruncateDecimal()
    56  
    57  		// remainder to community pool
    58  		feePool, err := h.k.FeePool.Get(ctx)
    59  		if err != nil {
    60  			return err
    61  		}
    62  
    63  		feePool.CommunityPool = feePool.CommunityPool.Add(remainder...)
    64  		err = h.k.FeePool.Set(ctx, feePool)
    65  		if err != nil {
    66  			return err
    67  		}
    68  
    69  		// add to validator account
    70  		if !coins.IsZero() {
    71  			accAddr := sdk.AccAddress(valAddr)
    72  			withdrawAddr, err := h.k.GetDelegatorWithdrawAddr(ctx, accAddr)
    73  			if err != nil {
    74  				return err
    75  			}
    76  
    77  			if err := h.k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, coins); err != nil {
    78  				return err
    79  			}
    80  		}
    81  	}
    82  
    83  	// Add outstanding to community pool
    84  	// The validator is removed only after it has no more delegations.
    85  	// This operation sends only the remaining dust to the community pool.
    86  	feePool, err := h.k.FeePool.Get(ctx)
    87  	if err != nil {
    88  		return err
    89  	}
    90  
    91  	feePool.CommunityPool = feePool.CommunityPool.Add(outstanding...)
    92  	err = h.k.FeePool.Set(ctx, feePool)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	// delete outstanding
    98  	err = h.k.DeleteValidatorOutstandingRewards(ctx, valAddr)
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	// remove commission record
   104  	err = h.k.DeleteValidatorAccumulatedCommission(ctx, valAddr)
   105  	if err != nil {
   106  		return err
   107  	}
   108  
   109  	// clear slashes
   110  	h.k.DeleteValidatorSlashEvents(ctx, valAddr)
   111  
   112  	// clear historical rewards
   113  	h.k.DeleteValidatorHistoricalRewards(ctx, valAddr)
   114  
   115  	// clear current rewards
   116  	err = h.k.DeleteValidatorCurrentRewards(ctx, valAddr)
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	return nil
   122  }
   123  
   124  // increment period
   125  func (h Hooks) BeforeDelegationCreated(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
   126  	val, err := h.k.stakingKeeper.Validator(ctx, valAddr)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	_, err = h.k.IncrementValidatorPeriod(ctx, val)
   132  	return err
   133  }
   134  
   135  // withdraw delegation rewards (which also increments period)
   136  func (h Hooks) BeforeDelegationSharesModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
   137  	val, err := h.k.stakingKeeper.Validator(ctx, valAddr)
   138  	if err != nil {
   139  		return err
   140  	}
   141  
   142  	del, err := h.k.stakingKeeper.Delegation(ctx, delAddr, valAddr)
   143  	if err != nil {
   144  		return err
   145  	}
   146  
   147  	if _, err := h.k.withdrawDelegationRewards(ctx, val, del); err != nil {
   148  		return err
   149  	}
   150  
   151  	return nil
   152  }
   153  
   154  // create new delegation period record
   155  func (h Hooks) AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
   156  	return h.k.initializeDelegation(ctx, valAddr, delAddr)
   157  }
   158  
   159  // record the slash event
   160  func (h Hooks) BeforeValidatorSlashed(ctx context.Context, valAddr sdk.ValAddress, fraction sdkmath.LegacyDec) error {
   161  	return h.k.updateValidatorSlashFraction(ctx, valAddr, fraction)
   162  }
   163  
   164  func (h Hooks) BeforeValidatorModified(_ context.Context, _ sdk.ValAddress) error {
   165  	return nil
   166  }
   167  
   168  func (h Hooks) AfterValidatorBonded(_ context.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error {
   169  	return nil
   170  }
   171  
   172  func (h Hooks) AfterValidatorBeginUnbonding(_ context.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error {
   173  	return nil
   174  }
   175  
   176  func (h Hooks) BeforeDelegationRemoved(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error {
   177  	return nil
   178  }
   179  
   180  func (h Hooks) AfterUnbondingInitiated(_ context.Context, _ uint64) error {
   181  	return nil
   182  }