87 lines
2.6 KiB
Go
87 lines
2.6 KiB
Go
package vesting
|
|
|
|
import (
|
|
"github.com/armon/go-metrics"
|
|
|
|
"github.com/cosmos/cosmos-sdk/telemetry"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
"github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
"github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
|
)
|
|
|
|
// NewHandler returns a handler for x/auth message types.
|
|
func NewHandler(ak keeper.AccountKeeper, bk types.BankKeeper) sdk.Handler {
|
|
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
|
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
|
|
|
switch msg := msg.(type) {
|
|
case *types.MsgCreateVestingAccount:
|
|
return handleMsgCreateVestingAccount(ctx, ak, bk, msg)
|
|
|
|
default:
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleMsgCreateVestingAccount(ctx sdk.Context, ak keeper.AccountKeeper, bk types.BankKeeper, msg *types.MsgCreateVestingAccount) (*sdk.Result, error) {
|
|
if err := bk.SendEnabledCoins(ctx, msg.Amount...); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if bk.BlockedAddr(msg.ToAddress) {
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", msg.ToAddress)
|
|
}
|
|
|
|
if acc := ak.GetAccount(ctx, msg.ToAddress); acc != nil {
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "account %s already exists", msg.ToAddress)
|
|
}
|
|
|
|
baseAccount := ak.NewAccountWithAddress(ctx, msg.ToAddress)
|
|
if _, ok := baseAccount.(*authtypes.BaseAccount); !ok {
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid account type; expected: BaseAccount, got: %T", baseAccount)
|
|
}
|
|
|
|
baseVestingAccount := types.NewBaseVestingAccount(baseAccount.(*authtypes.BaseAccount), msg.Amount.Sort(), msg.EndTime)
|
|
|
|
var acc authtypes.AccountI
|
|
|
|
if msg.Delayed {
|
|
acc = types.NewDelayedVestingAccountRaw(baseVestingAccount)
|
|
} else {
|
|
acc = types.NewContinuousVestingAccountRaw(baseVestingAccount, ctx.BlockTime().Unix())
|
|
}
|
|
|
|
ak.SetAccount(ctx, acc)
|
|
|
|
defer func() {
|
|
telemetry.IncrCounter(1, "new", "account")
|
|
|
|
for _, a := range msg.Amount {
|
|
if a.Amount.IsInt64() {
|
|
telemetry.SetGaugeWithLabels(
|
|
[]string{"tx", "msg", "create_vesting_account"},
|
|
float32(a.Amount.Int64()),
|
|
[]metrics.Label{telemetry.NewLabel("denom", a.Denom)},
|
|
)
|
|
}
|
|
}
|
|
}()
|
|
|
|
err := bk.SendCoins(ctx, msg.FromAddress, msg.ToAddress, msg.Amount)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ctx.EventManager().EmitEvent(
|
|
sdk.NewEvent(
|
|
sdk.EventTypeMessage,
|
|
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
|
),
|
|
)
|
|
|
|
return &sdk.Result{Events: ctx.EventManager().ABCIEvents()}, nil
|
|
}
|