Skip to content

Commit

Permalink
Merge pull request #201 from terra-money/feat/ibc/hooks
Browse files Browse the repository at this point in the history
feat: custom bank hooks
  • Loading branch information
tuky191 committed Nov 2, 2023
2 parents 0043608 + 8fb9783 commit 7fd040f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 6 deletions.
70 changes: 64 additions & 6 deletions custom/bank/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
accountkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

errorsmod "cosmossdk.io/errors"
custombankkeeper "github.com/terra-money/alliance/custom/bank/keeper"
customterratypes "github.com/terra-money/core/v2/custom/bank/types"

sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

type Keeper struct {
Expand Down Expand Up @@ -51,7 +51,6 @@ func (k *Keeper) SetHooks(bh customterratypes.BankHooks) *Keeper {
// SendCoins transfers amt coins from a sending account to a receiving account.
// An error is returned upon failure.
func (k Keeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error {
// BlockBeforeSend hook should always be called before the TrackBeforeSend hook.
err := k.BlockBeforeSend(ctx, fromAddr, toAddr, amt)
if err != nil {
return err
Expand All @@ -67,13 +66,72 @@ func (k Keeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.A
func (k Keeper) SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error {
senderAddr := k.ak.GetModuleAddress(senderModule)
if senderAddr == nil {
panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", senderModule))
panic(errorsmod.Wrapf(customterratypes.ErrUnknownAddress, "senderModule address %s is nil", senderModule))
}

recipientAcc := k.ak.GetModuleAccount(ctx, recipientModule)
if recipientAcc == nil {
panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", recipientModule))
panic(errorsmod.Wrapf(customterratypes.ErrUnknownAddress, "recipientModule address %s is nil", recipientModule))
}

return k.Keeper.SendCoins(ctx, senderAddr, recipientAcc.GetAddress(), amt)
}

// UndelegateCoins performs undelegation by crediting amt coins to an account with
// address addr. For vesting accounts, undelegation amounts are tracked for both
// vesting and vested coins. The coins are then transferred from a ModuleAccount
// address to the delegator address. If any of the undelegation amounts are
// negative, an error is returned.
func (k Keeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error {
err := k.BlockBeforeSend(ctx, moduleAccAddr, delegatorAddr, amt)
if err != nil {
return err
}
k.TrackBeforeSend(ctx, moduleAccAddr, delegatorAddr, amt)

return k.Keeper.UndelegateCoins(ctx, moduleAccAddr, delegatorAddr, amt)
}

// DelegateCoins performs delegation by deducting amt coins from an account with
// address addr. For vesting accounts, delegations amounts are tracked for both
// vesting and vested coins. The coins are then transferred from the delegator
// address to a ModuleAccount address. If any of the delegation amounts are negative,
// an error is returned.
func (k Keeper) DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error {
err := k.BlockBeforeSend(ctx, delegatorAddr, moduleAccAddr, amt)
if err != nil {
return err
}
k.TrackBeforeSend(ctx, delegatorAddr, moduleAccAddr, amt)

return k.Keeper.DelegateCoins(ctx, delegatorAddr, moduleAccAddr, amt)
}

// InputOutputCoins performs multi-send functionality. It accepts a series of
// inputs that correspond to a series of outputs. It returns an error if the
// inputs and outputs don't line up or if any single transfer of tokens fails.
func (k Keeper) InputOutputCoins(ctx sdk.Context, inputs []banktypes.Input, outputs []banktypes.Output) error {
// Only 1 input is allowed for all outputs check the following url:
// https://github.com/terra-money/cosmos-sdk/blob/release/v0.47.x/x/bank/types/msgs.go#L87-L89
//
// This if statement is added here too so we know
// when multiple inputs are allowed in the future
// because ErrMultipleSenders will fail to import
// because will be removed from the code.
if len(inputs) != 1 {
return banktypes.ErrMultipleSenders
}
input := inputs[0]
inputaddress := sdk.MustAccAddressFromBech32(input.Address)

for _, output := range outputs {
outputaddress := sdk.MustAccAddressFromBech32(output.Address)

err := k.BlockBeforeSend(ctx, inputaddress, outputaddress, output.Coins)
if err != nil {
return err
}
k.TrackBeforeSend(ctx, inputaddress, outputaddress, output.Coins)
}

return k.Keeper.InputOutputCoins(ctx, inputs, outputs)
}
12 changes: 12 additions & 0 deletions custom/bank/types/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package types

// DONTCOVER

import (
sdkerrors "cosmossdk.io/errors"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)

var (
ErrUnknownAddress = sdkerrors.Register(banktypes.ModuleName, 383838, "module account does not exist")
)

0 comments on commit 7fd040f

Please sign in to comment.