From 359c74c85caeb639a955e8b5f0c6e8b1a2ebac72 Mon Sep 17 00:00:00 2001 From: dreamer Date: Sun, 14 Apr 2024 17:49:13 +0800 Subject: [PATCH] refactor code --- modules/token/depinject.go | 11 +++-- modules/token/keeper/erc20.go | 32 ++++++++++++- modules/token/keeper/msg_server.go | 50 +++++-------------- modules/token/types/expected_keepers.go | 1 + simapp/app_v2.go | 6 +++ simapp/mocks/depinject.go | 25 ++++++++++ simapp/mocks/evm.go | 64 +++++++++++++++++++++++++ 7 files changed, 146 insertions(+), 43 deletions(-) create mode 100644 simapp/mocks/depinject.go create mode 100644 simapp/mocks/evm.go diff --git a/modules/token/depinject.go b/modules/token/depinject.go index 772a427f..7337668c 100644 --- a/modules/token/depinject.go +++ b/modules/token/depinject.go @@ -36,6 +36,7 @@ func (am AppModule) IsOnePerModuleType() {} // IsAppModule implements the appmodule.AppModule interface. func (am AppModule) IsAppModule() {} +// TokenInputs is the input of the Token module type TokenInputs struct { depinject.In @@ -45,15 +46,14 @@ type TokenInputs struct { AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper - - // TODO: EVMKeeper and ICS20Keeper must be injected in the production environment, where `optional:"true"` is only used for testing. - EVMKeeper types.EVMKeeper `optional:"true"` - ICS20Keeper types.ICS20Keeper `optional:"true"` + EVMKeeper types.EVMKeeper + ICS20Keeper types.ICS20Keeper // LegacySubspace is used solely for migration of x/params managed parameters LegacySubspace exported.Subspace `optional:"true"` } +// TokenOutputs is the output of the Token module type TokenOutputs struct { depinject.Out @@ -62,6 +62,9 @@ type TokenOutputs struct { } +// ProvideModule provides a module for the token with the given inputs and returns the token keeper and module. +// +// Takes TokenInputs as input parameters and returns TokenOutputs. func ProvideModule(in TokenInputs) TokenOutputs { // default to governance authority if not provided authority := authtypes.NewModuleAddress(govtypes.ModuleName) diff --git a/modules/token/keeper/erc20.go b/modules/token/keeper/erc20.go index 13865358..fc1e9337 100644 --- a/modules/token/keeper/erc20.go +++ b/modules/token/keeper/erc20.go @@ -3,6 +3,7 @@ package keeper import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -68,8 +69,35 @@ func (k Keeper) DeployERC20( return contractAddr, nil } - func (k Keeper) moduleAddress() common.Address { moduleAddr := k.accountKeeper.GetModuleAddress(types.ModuleName) return common.BytesToAddress(moduleAddr.Bytes()) -} \ No newline at end of file +} + +func (k Keeper) buildERC20Token( + ctx sdk.Context, + name string, + symbol string, + minUnit string, + scale uint32, +) (*v1.Token, error) { + if !k.HasMinUint(ctx, minUnit) { + if !k.ics20Keeper.HasTrace(ctx, minUnit) { + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "token: %s does not exist", minUnit) + } + return &v1.Token{ + Symbol: symbol, + Name: name, + Scale: scale, + MinUnit: minUnit, + Mintable: true, + Owner: k.accountKeeper.GetModuleAddress(types.ModuleName).String(), + }, nil + } + + token, err := k.getTokenByMinUnit(ctx, minUnit) + if err != nil { + return nil, err + } + return &token, nil +} diff --git a/modules/token/keeper/msg_server.go b/modules/token/keeper/msg_server.go index 5609b1dc..767a107e 100644 --- a/modules/token/keeper/msg_server.go +++ b/modules/token/keeper/msg_server.go @@ -272,48 +272,24 @@ func (m msgServer) UpdateParams( // DeployERC20 implements v1.MsgServer. func (m msgServer) DeployERC20(goCtx context.Context, msg *v1.MsgDeployERC20) (*v1.MsgDeployERC20Response, error) { - var ( - ctx = sdk.UnwrapSDKContext(goCtx) - name = msg.Name - symbol = msg.Symbol - scale = msg.Scale - minUnit = msg.MinUnit - token v1.Token - err error - ) - - if !m.k.HasMinUint(ctx, msg.MinUnit) { - if !m.k.ics20Keeper.HasTrace(ctx, msg.MinUnit) { - return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "token: %s not exist", msg.MinUnit) - } - token = v1.Token{ - Symbol: symbol, - Name: name, - Scale: scale, - MinUnit: msg.MinUnit, - Mintable: true, - Owner: m.k.accountKeeper.GetModuleAddress(types.ModuleName).String(), - } - } else { - token, err = m.k.getTokenByMinUnit(ctx, msg.MinUnit) - if err != nil { - return nil, err - } - if len(token.Contract) > 0 { - return nil, errorsmod.Wrapf(types.ErrERC20AlreadyExists, "token: %s already deployed erc20 contract: %s", token.Symbol, token.Contract) - } - name = token.Name - symbol = token.Symbol - scale = token.Scale - minUnit = token.MinUnit + ctx := sdk.UnwrapSDKContext(goCtx) + + token, err := m.k.buildERC20Token(ctx, msg.Name, msg.Symbol, msg.MinUnit, msg.Scale) + if err != nil { + return nil, err } - contractAddr, err := m.k.DeployERC20(ctx, name, symbol, minUnit, int8(scale)) + if len(token.Contract) > 0 { + return nil, errorsmod.Wrapf(types.ErrERC20AlreadyExists, "token: %s already deployed erc20 contract: %s", token.Symbol, token.Contract) + } + + contractAddr, err := m.k.DeployERC20(ctx, token.Name, token.Symbol, token.MinUnit, int8(token.Scale)) if err != nil { return nil, err } + token.Contract = contractAddr.String() - m.k.upsertToken(ctx, token) + m.k.upsertToken(ctx, *token) return &v1.MsgDeployERC20Response{}, nil } @@ -325,4 +301,4 @@ func (m msgServer) SwapFromERC20(context.Context, *v1.MsgSwapFromERC20) (*v1.Msg // SwapToERC20 implements v1.MsgServer. func (m msgServer) SwapToERC20(context.Context, *v1.MsgSwapToERC20) (*v1.MsgSwapToERC20Response, error) { panic("unimplemented") -} \ No newline at end of file +} diff --git a/modules/token/types/expected_keepers.go b/modules/token/types/expected_keepers.go index 84312491..5a766176 100644 --- a/modules/token/types/expected_keepers.go +++ b/modules/token/types/expected_keepers.go @@ -69,3 +69,4 @@ type EVMKeeper interface { type ICS20Keeper interface{ HasTrace(ctx sdk.Context, denom string) bool } + diff --git a/simapp/app_v2.go b/simapp/app_v2.go index 6d96b362..6ee3e471 100644 --- a/simapp/app_v2.go +++ b/simapp/app_v2.go @@ -104,6 +104,8 @@ import ( "github.com/irisnet/irismod/modules/token" tokenkeeper "github.com/irisnet/irismod/modules/token/keeper" tokentypes "github.com/irisnet/irismod/modules/token/types" + + "github.com/irisnet/irismod/simapp/mocks" ) var ( @@ -277,6 +279,10 @@ func NewSimApp( // For providing a custom inflation function for x/mint add here your // custom function that implements the minttypes.InflationCalculationFn // interface. + + // For providing a mock evm function for token module + mocks.ProvideEVMKeeper(), + mocks.ProvideICS20Keeper(), ), ) ) diff --git a/simapp/mocks/depinject.go b/simapp/mocks/depinject.go new file mode 100644 index 00000000..5abe9fb4 --- /dev/null +++ b/simapp/mocks/depinject.go @@ -0,0 +1,25 @@ +package mocks + +import ( + "github.com/ethereum/go-ethereum/common" + + tokentypes "github.com/irisnet/irismod/modules/token/types" +) + +// ProvideEVMKeeper returns an instance of tokentypes.EVMKeeper. +// +// No parameters. +// Returns a tokentypes.EVMKeeper. +func ProvideEVMKeeper() tokentypes.EVMKeeper { + return &evm{ + erc20s: make(map[common.Address]*erc20), + } +} + +// ProvideICS20Keeper returns an instance of tokentypes.ICS20Keeper. +// +// No parameters. +// Returns a tokentypes.ICS20Keeper. +func ProvideICS20Keeper() tokentypes.ICS20Keeper { + return &transferKeeper{} +} \ No newline at end of file diff --git a/simapp/mocks/evm.go b/simapp/mocks/evm.go new file mode 100644 index 00000000..0cc36668 --- /dev/null +++ b/simapp/mocks/evm.go @@ -0,0 +1,64 @@ +package mocks + +import ( + "context" + "math/big" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/vm" + + tokentypes "github.com/irisnet/irismod/modules/token/types" + "github.com/irisnet/irismod/types" +) + +var ( + _ tokentypes.EVMKeeper = (*evm)(nil) + _ tokentypes.ICS20Keeper = (*transferKeeper)(nil) +) + +type evm struct { + erc20s map[common.Address]*erc20 +} + +// ApplyMessage implements types.EVMKeeper. +func (e *evm) ApplyMessage(ctx sdk.Context, msg core.Message, tracer vm.EVMLogger, commit bool) (*types.Result, error) { + panic("unimplemented") +} + +// ChainID implements types.EVMKeeper. +func (e *evm) ChainID() *big.Int { + return big.NewInt(16688) +} + +// EstimateGas implements types.EVMKeeper. +func (e *evm) EstimateGas(ctx context.Context, req *types.EthCallRequest) (uint64, error) { + return 3000000, nil +} + +// FeeDenom implements types.EVMKeeper. +func (e *evm) FeeDenom() string { + return "eris" +} + +// SupportedKey implements types.EVMKeeper. +func (e *evm) SupportedKey(pubKey cryptotypes.PubKey) bool { + return true +} + +type erc20 struct { + scale int8 + name, symbol string + + balance map[common.Address]*big.Int +} + +type transferKeeper struct{} + +// HasTrace implements types.ICS20Keeper. +func (t *transferKeeper) HasTrace(ctx sdk.Context, denom string) bool { + return true +}