136 lines
3.5 KiB
Go
136 lines
3.5 KiB
Go
package keeper
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
|
|
gogoproto "github.com/cosmos/gogoproto/proto"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
|
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
)
|
|
|
|
var _ types.MsgServer = msgServer{}
|
|
|
|
type msgServer struct {
|
|
ak AccountKeeper
|
|
}
|
|
|
|
// NewMsgServerImpl returns an implementation of the x/auth MsgServer interface.
|
|
func NewMsgServerImpl(ak AccountKeeper) types.MsgServer {
|
|
return &msgServer{
|
|
ak: ak,
|
|
}
|
|
}
|
|
|
|
func (ms msgServer) NonAtomicExec(ctx context.Context, msg *types.MsgNonAtomicExec) (*types.MsgNonAtomicExecResponse, error) {
|
|
if msg.Signer == "" {
|
|
return nil, errors.New("empty signer address string is not allowed")
|
|
}
|
|
|
|
signer, err := ms.ak.AddressCodec().StringToBytes(msg.Signer)
|
|
if err != nil {
|
|
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid signer address: %s", err)
|
|
}
|
|
|
|
if len(msg.Msgs) == 0 {
|
|
return nil, sdkerrors.ErrInvalidRequest.Wrapf("messages cannot be empty")
|
|
}
|
|
|
|
msgs, err := msg.GetMessages()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
results, err := ms.ak.NonAtomicMsgsExec(ctx, signer, msgs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &types.MsgNonAtomicExecResponse{
|
|
Results: results,
|
|
}, nil
|
|
}
|
|
|
|
func (ms msgServer) UpdateParams(ctx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
|
|
if ms.ak.authority != msg.Authority {
|
|
return nil, fmt.Errorf(
|
|
"expected authority account as only signer for proposal message; invalid authority; expected %s, got %s",
|
|
ms.ak.authority, msg.Authority)
|
|
}
|
|
|
|
if err := msg.Params.Validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := ms.ak.Params.Set(ctx, msg.Params); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &types.MsgUpdateParamsResponse{}, nil
|
|
}
|
|
|
|
func (ms msgServer) MigrateAccount(ctx context.Context, msg *types.MsgMigrateAccount) (*types.MsgMigrateAccountResponse, error) {
|
|
signer, err := ms.ak.AddressCodec().StringToBytes(msg.Signer)
|
|
if err != nil {
|
|
return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid signer address: %s", err)
|
|
}
|
|
|
|
acc := ms.ak.GetAccount(ctx, signer)
|
|
if acc == nil {
|
|
return nil, sdkerrors.ErrUnknownAddress.Wrapf("account %s does not exist", signer)
|
|
}
|
|
|
|
// check if account type is valid or not
|
|
_, isBaseAccount := (acc).(*types.BaseAccount)
|
|
if !isBaseAccount {
|
|
return nil, status.Error(codes.InvalidArgument, "only BaseAccount can be migrated")
|
|
}
|
|
|
|
// unwrap any msg
|
|
initMsg, err := unpackAnyRaw(msg.AccountInitMsg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
initResp, err := ms.ak.AccountsModKeeper.MigrateLegacyAccount(ctx, signer, acc.GetAccountNumber(), msg.AccountType, initMsg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// account is then removed from state
|
|
ms.ak.RemoveAccount(ctx, acc)
|
|
|
|
initRespAny, err := codectypes.NewAnyWithValue(initResp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &types.MsgMigrateAccountResponse{InitResponse: initRespAny}, nil
|
|
}
|
|
|
|
func unpackAnyRaw(m *codectypes.Any) (gogoproto.Message, error) {
|
|
if m == nil {
|
|
return nil, fmt.Errorf("cannot unpack nil any")
|
|
}
|
|
split := strings.Split(m.TypeUrl, "/")
|
|
name := split[len(split)-1]
|
|
typ := gogoproto.MessageType(name)
|
|
if typ == nil {
|
|
return nil, fmt.Errorf("no message type found for %s", name)
|
|
}
|
|
concreteMsg := reflect.New(typ.Elem()).Interface().(gogoproto.Message)
|
|
err := gogoproto.Unmarshal(m.Value, concreteMsg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return concreteMsg, nil
|
|
}
|